GitHub - SwiftExtensions/SwiftUIExtensions: Grid layouts, shapes, charts, slider...
source link: https://github.com/SwiftExtensions/SwiftUIExtensions
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.md
SwiftUI Extensions
Collection of useful SwiftUI extensions and elements
- Grid based layouts
- Sliders (horizontal, vertical, point)
- Custom shapes
- Data charts
- Supports all apple platforms
- SwiftUI code patterns (Styles, EnvironmentValues, ViewBuilder)
- Active development for production apps
Open /Demo/SwiftUIExtensionsDemo.xcodeproj
for more examples for iOS, macOS, watchOS and tvOS
Layouts
Modular Grid
Grid(colors) { Rectangle() .foregroundColor($0) } .gridStyle( ModularGridStyle(columns: .min(100), rows: .min(100)) )
Staggered Grid
Grid(1...69, id: \.self) { index in Image("\(index)") .resizable() .scaledToFit() } .gridStyle( StaggeredGridStyle(tracks: 8, axis: .horizontal, spacing: 4) )
Tracks
Tracks setting allows you to customize grid behaviour to your specific use-case. Both Modular and Staggered grid use tracks value to calculate layout. In Modular layout both columns and rows are tracks.
public enum Tracks: Hashable { case count(Int) case fixed(CGFloat) case min(CGFloat) }
Count
Grid is split into equal fractions of size provided by a parent view.
ModularGridStyle(columns: 3, rows: 3) StaggeredGridStyle(tracks: 8)
Fixed
Item size is fixed to a specific width or height.
ModularGridStyle(columns: .fixed(100), rows: .fixed(100)) StaggeredGridStyle(tracks: .fixed(100))
Min
Autolayout respecting a min item width or height.
ModularGridStyle(columns: .min(100), rows: .min(100)) StaggeredGridStyle(tracks: .min(100))
Preferences
Get item size and position with preferences
struct CardsView: View { @State var selection: Int = 0 var body: some View { Grid(0..<100) { number in Card(title: "\(number)") .onTapGesture { self.selection = number } } .padding() .overlayPreferenceValue(GridItemBoundsPreferencesKey.self) { preferences in RoundedRectangle(cornerRadius: 16) .strokeBorder(lineWidth: 4) .foregroundColor(.white) .frame( width: preferences[self.selection].width, height: preferences[self.selection].height ) .position( x: preferences[self.selection].midX, y: preferences[self.selection].midY ) .animation(.linear) } } }
Sliders
Highly customizable sliders and tracks
Simple gradient value slider style
HSlider(value: $value, track: LinearGradient(gradient: Gradient(colors: [.red, .orange, .yellow, .green, .blue, .purple, .pink]), startPoint: .leading, endPoint: .trailing) .frame(height: 8) .cornerRadius(4) )
Multivalue track
ZStack { HTrack(value: value1, view: Capsule().foregroundColor(.red)).opacity(0.5) HTrack(value: value2, view: Capsule().foregroundColor(.blue)).opacity(0.5) HTrack(value: value3, view: Capsule().foregroundColor(.green)).opacity(0.5) } .animation(.spring()) .frame(height: 8) .background(Color.secondary.opacity(0.25))
Complex range slider style
HRangeSlider(range: $range, in: 0.0...1.0, step: 0.01, track: HRangeTrack( range: range, view: LinearGradient(gradient: Gradient(colors: [.yellow, .orange, .red]), startPoint: .leading, endPoint: .trailing), mask: Rectangle(), configuration: .init( offsets: 32 ) ) .background(Color.secondary.opacity(0.25)) .cornerRadius(16) .padding(.vertical, 8) .animation(.easeInOut(duration: 0.5)), lowerThumb: Capsule() .foregroundColor(.white), upperThumb: Capsule() .foregroundColor(.white), configuration: .init( thumbSize: CGSize(width: 32, height: 64), thumbInteractiveSize: CGSize(width: 44, height: 64) ), onEditingChanged: { print($0) } ) .frame(height: 64)
Complex point slider style
XYSlider(x: $x, y: $y, track: RoundedRectangle(cornerRadius: 24) .foregroundColor( Color(hue: 0.67, saturation: y, brightness: 1.0) ), thumb: ZStack { Capsule().frame(width: 12).foregroundColor(.white) Capsule().frame(height: 12).foregroundColor(.white) } .compositingGroup() .rotationEffect(Angle(radians: x * 10)) .shadow(radius: 3), configuration: .init( options: .interactiveTrack, thumbSize: CGSize(width: 48, height: 48) ) ) .frame(height: 256) .shadow(radius: 3) .padding()
Data Visualization
Build custom charts with SwiftUI
Line Chart
Chart(data: [0.1, 0.3, 0.2, 0.5, 0.4, 0.9, 0.1]) .chartStyle( LineChartStyle(.quadCurve, lineColor: .blue, lineWidth: 5) )
Area Chart
Chart(data: [0.1, 0.3, 0.2, 0.5, 0.4, 0.9, 0.1]) .chartStyle( AreaChartStyle(.quadCurve, fill: LinearGradient(gradient: .init(colors: [Color.blue.opacity(0.2), Color.blue.opacity(0.05)]), startPoint: .top, endPoint: .bottom) ) )
Stacked Area Chart
Chart(data: matrix) .chartStyle( StackedAreaChartStyle(.quadCurve, colors: [.yellow, .orange, .red]) )
Column Chart
Chart(data: [0.1, 0.3, 0.2, 0.5, 0.4, 0.9, 0.1]) .chartStyle( ColumnChartStyle(column: Capsule().foregroundColor(.green), spacing: 2) )
Stacked Column Chart
Chart(data: matrix) .chartStyle( StackedColumnChartStyle(spacing: 2, colors: [.yellow, .orange, .red]) )
Shapes
Regular Polygons
Pentagon() Hexagon() RegularPolygon(sides: 32)
Lines and Curves
QuadCurve(unitPoints: [ UnitPoint(x: 0.1, y: 0.1), UnitPoint(x: 0.5, y: 0.9), UnitPoint(x: 0.9, y: 0.1) ]) .stroke(Color.blue, style: .init(lineWidth: 2, lineCap: .round)) .frame(height: 200)
Patterns
GridPattern(horizontalLines: 20, verticalLines: 40) .stroke(Color.white.opacity(0.3), style: .init(lineWidth: 1, lineCap: .round)) .frame(height: 200) .background(Color.blue) .padding()
SDKs
- iOS 13+
- Mac Catalyst 13.0+
- macOS 10.15+
- watchOS 6+
- Xcode 11.0+
Roadmap
- Animations
- 'CSS Grid'-like features for Modular Grid
- View Modifiers
- Rounded regular polygons
- Bar chart style
Code Contibutions
Feel free to contribute via fork/pull request to master branch. If you want to request a feature or report a bug please start a new issue.
Coffee Contibutions
If you find this project useful please consider becoming a sponsor.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK