├── swift-ui-logo.png
├── assets
├── images
│ ├── list
│ │ ├── 1.png
│ │ ├── 2.png
│ │ └── 3.png
│ ├── input
│ │ ├── tap
│ │ │ └── 1.png
│ │ ├── button
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ │ ├── picker
│ │ │ └── 1.png
│ │ ├── slider
│ │ │ └── 1.png
│ │ ├── toggle
│ │ │ └── 1.png
│ │ ├── textfield
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ │ └── date_picker
│ │ │ └── 1.png
│ ├── view
│ │ ├── text
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ ├── image
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ └── 4.png
│ │ └── shape
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ ├── navigation
│ │ └── 1.png
│ ├── layout
│ │ ├── hstack
│ │ │ └── 1.png
│ │ ├── vstack
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ │ ├── zstack
│ │ │ └── 1.png
│ │ └── background
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ └── containers
│ │ ├── group
│ │ └── 1.png
│ │ ├── tabview
│ │ └── 1.png
│ │ └── navigationview
│ │ ├── 1.png
│ │ └── 2.png
└── swift-ui-logo.png
├── LICENSE
├── .gitignore
├── .github
└── workflows
│ └── aws.yml
└── README.md
/swift-ui-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/swift-ui-logo.png
--------------------------------------------------------------------------------
/assets/images/list/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/list/1.png
--------------------------------------------------------------------------------
/assets/images/list/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/list/2.png
--------------------------------------------------------------------------------
/assets/images/list/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/list/3.png
--------------------------------------------------------------------------------
/assets/swift-ui-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/swift-ui-logo.png
--------------------------------------------------------------------------------
/assets/images/input/tap/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/tap/1.png
--------------------------------------------------------------------------------
/assets/images/view/text/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/text/1.png
--------------------------------------------------------------------------------
/assets/images/view/text/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/text/2.png
--------------------------------------------------------------------------------
/assets/images/view/text/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/text/3.png
--------------------------------------------------------------------------------
/assets/images/navigation/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/navigation/1.png
--------------------------------------------------------------------------------
/assets/images/view/image/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/image/1.png
--------------------------------------------------------------------------------
/assets/images/view/image/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/image/2.png
--------------------------------------------------------------------------------
/assets/images/view/image/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/image/3.png
--------------------------------------------------------------------------------
/assets/images/view/image/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/image/4.png
--------------------------------------------------------------------------------
/assets/images/view/shape/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/shape/1.png
--------------------------------------------------------------------------------
/assets/images/view/shape/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/view/shape/2.png
--------------------------------------------------------------------------------
/assets/images/input/button/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/button/1.png
--------------------------------------------------------------------------------
/assets/images/input/button/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/button/2.png
--------------------------------------------------------------------------------
/assets/images/input/picker/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/picker/1.png
--------------------------------------------------------------------------------
/assets/images/input/slider/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/slider/1.png
--------------------------------------------------------------------------------
/assets/images/input/toggle/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/toggle/1.png
--------------------------------------------------------------------------------
/assets/images/layout/hstack/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/layout/hstack/1.png
--------------------------------------------------------------------------------
/assets/images/layout/vstack/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/layout/vstack/1.png
--------------------------------------------------------------------------------
/assets/images/layout/vstack/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/layout/vstack/2.png
--------------------------------------------------------------------------------
/assets/images/layout/zstack/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/layout/zstack/1.png
--------------------------------------------------------------------------------
/assets/images/containers/group/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/containers/group/1.png
--------------------------------------------------------------------------------
/assets/images/input/textfield/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/textfield/1.png
--------------------------------------------------------------------------------
/assets/images/input/textfield/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/textfield/2.png
--------------------------------------------------------------------------------
/assets/images/containers/tabview/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/containers/tabview/1.png
--------------------------------------------------------------------------------
/assets/images/input/date_picker/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/input/date_picker/1.png
--------------------------------------------------------------------------------
/assets/images/layout/background/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/layout/background/1.png
--------------------------------------------------------------------------------
/assets/images/layout/background/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/layout/background/2.png
--------------------------------------------------------------------------------
/assets/images/containers/navigationview/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/containers/navigationview/1.png
--------------------------------------------------------------------------------
/assets/images/containers/navigationview/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reverse-developer/SwiftUi-cheatsheet-GiSheet/HEAD/assets/images/containers/navigationview/2.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Giridharan Venkatapathy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
--------------------------------------------------------------------------------
/.github/workflows/aws.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build and push a new container image to Amazon ECR,
2 | # and then will deploy a new task definition to Amazon ECS, when a release is created
3 | #
4 | # To use this workflow, you will need to complete the following set-up steps:
5 | #
6 | # 1. Create an ECR repository to store your images.
7 | # For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`.
8 | # Replace the value of `ECR_REPOSITORY` in the workflow below with your repository's name.
9 | # Replace the value of `aws-region` in the workflow below with your repository's region.
10 | #
11 | # 2. Create an ECS task definition, an ECS cluster, and an ECS service.
12 | # For example, follow the Getting Started guide on the ECS console:
13 | # https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun
14 | # Replace the values for `service` and `cluster` in the workflow below with your service and cluster names.
15 | #
16 | # 3. Store your ECS task definition as a JSON file in your repository.
17 | # The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`.
18 | # Replace the value of `task-definition` in the workflow below with your JSON file's name.
19 | # Replace the value of `container-name` in the workflow below with the name of the container
20 | # in the `containerDefinitions` section of the task definition.
21 | #
22 | # 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
23 | # See the documentation for each action used below for the recommended IAM policies for this IAM user,
24 | # and best practices on handling the access key credentials.
25 |
26 | on:
27 | release:
28 | types: [created]
29 |
30 | name: Deploy to Amazon ECS
31 |
32 | jobs:
33 | deploy:
34 | name: Deploy
35 | runs-on: ubuntu-latest
36 | environment: production
37 |
38 | steps:
39 | - name: Checkout
40 | uses: actions/checkout@v2
41 |
42 | - name: Configure AWS credentials
43 | uses: aws-actions/configure-aws-credentials@v1
44 | with:
45 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
46 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
47 | aws-region: us-east-2
48 |
49 | - name: Login to Amazon ECR
50 | id: login-ecr
51 | uses: aws-actions/amazon-ecr-login@v1
52 |
53 | - name: Build, tag, and push image to Amazon ECR
54 | id: build-image
55 | env:
56 | ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
57 | ECR_REPOSITORY: my-ecr-repo
58 | IMAGE_TAG: ${{ github.sha }}
59 | run: |
60 | # Build a docker container and
61 | # push it to ECR so that it can
62 | # be deployed to ECS.
63 | docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
64 | docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
65 | echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
66 |
67 | - name: Fill in the new image ID in the Amazon ECS task definition
68 | id: task-def
69 | uses: aws-actions/amazon-ecs-render-task-definition@v1
70 | with:
71 | task-definition: task-definition.json
72 | container-name: sample-app
73 | image: ${{ steps.build-image.outputs.image }}
74 |
75 | - name: Deploy Amazon ECS task definition
76 | uses: aws-actions/amazon-ecs-deploy-task-definition@v1
77 | with:
78 | task-definition: ${{ steps.task-def.outputs.task-definition }}
79 | service: sample-app-service
80 | cluster: default
81 | wait-for-service-stability: true
82 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwiftUI GiSheet - The Smart - Cheatsheet to everything on SwiftUI
2 |
3 |
4 | 
5 |
6 |
7 | ### Table of Contents
8 | - [Resource](#resource)
9 | - [UIKit equivalent in SwiftUI](#uikit-equivalent-in-swiftui)
10 | - [View](#view)
11 | - [Text](#text)
12 | - [Label](#label)
13 | - [TextEditor](#texteditor)
14 | - [Image](#image)
15 | - [Shape](#shape)
16 | - [ProgressView](#progressview)
17 | - [Map](#map)
18 | - [Layout](#layout)
19 | - [Background](#background)
20 | - [VStack](#vstack)
21 | - [HStack](#hstack)
22 | - [ZStack](#zstack)
23 | - [LazyVStack](#lazyvstack)
24 | - [LazyHStack](#lazyhstack)
25 | - [LazyVGrid](#lazyvgrid)
26 | - [LazyHGrid](#lazyhgrid)
27 | - [Input](#input)
28 | - [Toggle](#toggle)
29 | - [Button](#button)
30 | - [TextField](#textfield)
31 | - [Slider](#slider)
32 | - [Date Picker](#date-picker)
33 | - [Picker](#picker)
34 | - [Stepper](#stepper)
35 | - [Tap](#tap)
36 | - [Gesture](#gesture)
37 | - [OnChange](#onChange)
38 | - [List](#list)
39 | - [Containers](#containers)
40 | - [NavigationView](#navigationview)
41 | - [TabView](#tabView)
42 | - [Group](#group)
43 | - [Alerts and Action Sheets](#alerts-and-action-sheets)
44 | - [Navigation](#navigation)
45 | - [Work with UIKit](#work-with-uikit)
46 | - [Navigate to ViewController](#navigate-to-viewcontroller)
47 | - [Use UIKit and SwiftUI Views Together](#use-uikit-and-swiftui-views-together)
48 |
49 | # Resource
50 | - [SwiftUI Tutorials (Official)](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)
51 | - [Introducing SwiftUI: Building Your First App (Official)](https://developer.apple.com/videos/play/wwdc2019/204/)
52 | - [SwiftUI: Getting Started Raywenderlich](https://www.raywenderlich.com/3715234-swiftui-getting-started)
53 | - [SwiftUI Essentials (Official)](https://developer.apple.com/videos/play/wwdc2019/216)
54 | - [SwiftUI - How to setup a project](https://medium.com/@martinlasek/swiftui-getting-started-372389fff423)
55 | - [About SwiftUI](https://github.com/Juanpe/About-SwiftUI)
56 |
57 |
58 | # UIKit equivalent in SwiftUI
59 | | UIKit | [SwiftUI](https://developer.apple.com/xcode/swiftui/) |
60 | | ----------- | ----------- |
61 | | UILabel | [Text](#text) & [Label](#label)|
62 | | UIImageView | [Image](#image) |
63 | | UITextField | [TextField](#textfield) |
64 | | UITextView | [TextEditor](#texteditor) |
65 | | UISwitch | [Toggle](#toggle) |
66 | | UISlider | [Slider](#slider) |
67 | | UIButton | [Button](#button) |
68 | | UITableView | [List](#list) |
69 | | UICollectionView | [LazyVGrid](#lazyvgrid) / [LazyHGrid](#lazyhgrid) |
70 | | UINavigationController | [NavigationView](#navigationview) |
71 | | UITabBarController | [TabView](#tabview) |
72 | | UIAlertController with style .alert | [Alert](#alerts-and-action-sheets) |
73 | | UIAlertController with style .actionSheet | [ActionSheet](#alerts-and-action-sheets) |
74 | | UIStackView with horizontal axis| [HStack](#hstack) / [LazyHStack](#lazyhstack) |
75 | | UIStackView with vertical axis| [VStack](#vstack) / [LazyVStack](#lazyvstack) |
76 | | UISegmentedControl | [Picker](#picker) |
77 | | UIStepper | [Stepper](#stepper) |
78 | | UIDatePicker | [DatePicker](#date-picker) |
79 | | NSAttributedString | No equivalent (use [Text](#text)) |
80 | | MapKit | [Map](#map) |
81 | | UIProgressView | [ProgressView](#progressview) |
82 |
83 |
84 |
85 | # View
86 |
87 | ### Text
88 |
89 | To show a **text** in UI simply write:
90 | ``` swift
91 | Text("Hello World")
92 | ```
93 |
94 | Screenshot
95 |
96 |
97 | 
98 |
99 |
100 |
101 |
102 | To add style
103 |
104 | ``` swift
105 | Text("Hello World")
106 | .font(.largeTitle)
107 | .fontWeight(.heavy)
108 | .foregroundColor(Color.red)
109 | .multilineTextAlignment(.leading)
110 | .lineLimit(1)
111 | .padding(.bottom)
112 | .frame(width: 400.0, height: 200.0)
113 | ```
114 |
115 | Screenshot
116 |
117 |
118 | 
119 |
120 |
121 |
122 |
123 | To format text inside text view
124 |
125 | ``` swift
126 | static let dateFormatter: DateFormatter = {
127 | let formatter = DateFormatter()
128 | formatter.dateStyle = .long
129 | return formatter
130 | }()
131 |
132 | var now = Date()
133 | var body: some View {
134 | Text("Task due date: \(now, formatter: Self.dateFormatter)")
135 | }
136 | ```
137 |
138 | Screenshot
139 |
140 |
141 | 
142 |
143 |
144 |
145 |
146 | ### Label
147 | Labels are a much-needed addition in the latest SwiftUI iteration. They let you set icons alongside text with the following line of code.
148 |
149 | ``` swift
150 | Label("SwiftUI CheatSheet 2.0", systemImage: "up.icloud")
151 | ```
152 |
153 | It's possible to set URL, upon clicking which will redirect to browser.
154 |
155 | ``` swift
156 | Link("Click me",destination: URL(string: "your_url")!)
157 | ```
158 |
159 | ### TextEditor
160 | Multi-line scrollable UITextViews natively in SwiftUI
161 |
162 | ``` swift
163 | TextEditor(text: $currentText)
164 | .onChange(of: clearText) { value in
165 | if clearText {
166 | currentText = ""
167 | }
168 | }
169 | ```
170 |
171 | ### Map
172 | MapKit natively in SwiftUI
173 |
174 | ``` swift
175 | Map(mapRect:interactionModes:showsUserLocation: userTrackingMode:
176 |
177 | @State private var region = MKCoordinateRegion(
178 | center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
179 | span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
180 | )
181 |
182 | Map(coordinateRegion: $region)
183 | ```
184 |
185 | ### Image
186 | To show image
187 |
188 | ``` swift
189 | Image("hello_world") //image name is hello_world
190 | ```
191 |
192 | Screenshot
193 |
194 |
195 | 
196 |
197 |
198 |
199 |
200 | To use system icon
201 | ``` swift
202 | Image(systemName: "cloud.heavyrain.fill")
203 | .resizable()
204 | .aspectRatio(contentMode: .fit)
205 | .padding(.bottom)
206 | .clipShape(Circle())
207 | .overlay(Circle().stroke(Color.gray, lineWidth: 4))
208 | .shadow(radius: 7)
209 | ```
210 |
211 | Screenshot
212 |
213 |
214 | 
215 |
216 |
217 |
218 |
219 | you can add style to system icon set
220 |
221 | ``` swift
222 | Image(systemName: "cloud.heavyrain.fill")
223 | .foregroundColor(.red)
224 | .font(.largeTitle)
225 | ```
226 |
227 | Screenshot
228 |
229 |
230 | 
231 |
232 |
233 |
234 |
235 | Add style to Image
236 |
237 | ``` swift
238 | Image("hello_world")
239 | .resizable() //it will sized so that it fills all the available space
240 | .aspectRatio(contentMode: .fill)
241 | .padding(.bottom)
242 | ```
243 |
244 | Screenshot
245 |
246 |
247 | 
248 |
249 |
250 |
251 |
252 | ### Shape
253 |
254 | To create Rectangle
255 |
256 | ``` swift
257 | Rectangle()
258 | .fill(Color.red)
259 | .frame(width: 200, height: 200)
260 | ```
261 |
262 | Screenshot
263 |
264 |
265 | 
266 |
267 |
268 |
269 |
270 | To create circle
271 |
272 | ``` swift
273 | Circle()
274 | .fill(Color.blue)
275 | .frame(width: 50, height: 50)
276 | ```
277 |
278 | Screenshot
279 |
280 |
281 | 
282 |
283 |
284 |
285 |
286 | ### ProgressView
287 |
288 | To show a ProgressView
289 | ``` swift
290 | ProgressView("Text", value: 10, total: 100)
291 | ```
292 |
293 | # Layout
294 |
295 | ### Background
296 | To use image as a background
297 |
298 | ``` swift
299 | Text("Hello World")
300 | .font(.largeTitle)
301 | .background(
302 | Image("hello_world")
303 | .resizable()
304 | .frame(width: 100, height: 100)
305 | )
306 | ```
307 |
308 | Screenshot
309 |
310 |
311 | 
312 |
313 |
314 |
315 |
316 | Gradient background
317 |
318 | ``` swift
319 | Text("Hello World")
320 | .background(
321 | LinearGradient(
322 | gradient: Gradient(colors: [.white, .red, .black]),
323 | startPoint: .leading,
324 | endPoint: .trailing
325 | ),
326 | cornerRadius: 0
327 | )
328 | ```
329 |
330 | Screenshot
331 |
332 |
333 | 
334 |
335 |
336 |
337 |
338 | ### VStack
339 | Shows child view vertically
340 |
341 | ``` swift
342 | VStack {
343 | Text("Hello")
344 | Text("World")
345 | }
346 | ```
347 |
348 | Screenshot
349 |
350 |
351 | 
352 |
353 |
354 |
355 |
356 | Styling
357 |
358 | ``` swift
359 | VStack(alignment: .leading, spacing: 20) {
360 | Text("Hello")
361 | Divider()
362 | Text("World")
363 | }
364 | ```
365 |
366 | Screenshot
367 |
368 |
369 | 
370 |
371 |
372 |
373 |
374 | ### HStack
375 | Shows child view horizontally
376 |
377 | ``` swift
378 | HStack {
379 | Text("Hello")
380 | Text("World")
381 | }
382 | ```
383 |
384 | Screenshot
385 |
386 |
387 | 
388 |
389 |
390 |
391 |
392 | ### ZStack
393 |
394 | To create overlapping content use ZStack
395 |
396 | ``` swift
397 | ZStack() {
398 | Image("hello_world")
399 | Text("Hello World")
400 | .font(.largeTitle)
401 | .background(Color.black)
402 | .foregroundColor(.white)
403 | }
404 | ```
405 |
406 | Screenshot
407 |
408 |
409 | 
410 |
411 |
412 |
413 |
414 | ### LazyVStack
415 |
416 | It loads content as and when it’s needed thus improving performance
417 |
418 | ``` swift
419 | ScrollView(.horizontal) {
420 | LazyVStack(spacing: 10) {
421 | ForEach(0..<1000) { index in
422 | Text("\(index)")
423 | .frame(width: 100, height: 200)
424 | .border(Color.gray.opacity(0.5), width: 0.5)
425 | .background(Color.blue)
426 | .cornerRadius(6)
427 | }
428 | }
429 | .padding(.leading, 10)
430 | }
431 | ```
432 |
433 | ### LazyHStack
434 |
435 | It loads content as and when it’s needed thus improving performance
436 |
437 | ``` swift
438 | ScrollView(.horizontal) {
439 | LazyHStack(spacing: 10) {
440 | ForEach(0..<1000) { index in
441 | Text("\(index)")
442 | .frame(width: 100, height: 200)
443 | .border(Color.gray.opacity(0.5), width: 0.5)
444 | .background(Color.blue)
445 | .cornerRadius(6)
446 | }
447 | }
448 | .padding(.leading, 10)
449 | }
450 | ```
451 |
452 | ### LazyVGrid
453 | A containers for grid-based layouts that let you set child views vertically in LazyVGrid. Each element of a SwiftUI grid is a GridItem. We can set the alignments, spacing, and size of the GridItem
454 |
455 |
456 | ``` swift
457 | struct ContentView: View {
458 |
459 | let colors: [Color] = [.red, .green, .yellow, .blue]
460 |
461 | var columns: [GridItem] =
462 | Array(repeating: .init(.flexible(), alignment: .center), count: 3)
463 |
464 | var body: some View {
465 | ScrollView {
466 | LazyVGrid(columns: columns, spacing: 10) {
467 | ForEach(0...100, id: \.self) { index in
468 | Text("Tab \(index)")
469 | .frame(width: 110, height: 200)
470 | .background(colors[index % colors.count])
471 | .cornerRadius(8)
472 | }
473 | }
474 | }
475 | }
476 | }
477 |
478 | ```
479 |
480 | ### LazyHGrid
481 | A containers for grid-based layouts that let you set child views horizontally in LazyHGrid
482 |
483 |
484 | ``` swift
485 | struct ContentView: View {
486 |
487 | let colors: [Color] = [.red, .green, .yellow, .blue]
488 |
489 | var columns: [GridItem] =
490 | Array(repeating: .init(.flexible(), alignment: .center), count: 3)
491 |
492 | var body: some View {
493 | ScrollView {
494 | LazyHGrid(columns: columns, spacing: 10) {
495 | ForEach(0...100, id: \.self) { index in
496 | Text("Tab \(index)")
497 | .frame(width: 110, height: 200)
498 | .background(colors[index % colors.count])
499 | .cornerRadius(8)
500 | }
501 | }
502 | }
503 | }
504 | }
505 |
506 | ```
507 |
508 | # Input
509 |
510 | ### Toggle
511 |
512 | Toggle lets users move between true and false states
513 |
514 | ``` swift
515 | @State var isShowing = true //state
516 |
517 | Toggle(isOn: $isShowing) {
518 | Text("Hello World")
519 | }.padding()
520 | ```
521 |
522 | Screenshot
523 |
524 |
525 | 
526 |
527 |
528 |
529 |
530 | ### Button
531 | To create button
532 |
533 | ``` swift
534 | Button(
535 | action: {
536 | // do something
537 | },
538 | label: { Text("Click Me") }
539 | )
540 | ```
541 |
542 | Screenshot
543 |
544 |
545 | 
546 |
547 |
548 |
549 |
550 | To create image Button
551 |
552 | ``` swift
553 | Button(
554 | action: {
555 | // do something
556 | },
557 | label: { Image("hello_world") }
558 | )
559 | ```
560 |
561 |
562 | ### TextField
563 |
564 | It heavily relies in state, simply create a state and pass it as it will bind to it
565 |
566 | ``` swift
567 | @State var fullName: String = "Joe" //create State
568 |
569 | TextField($fullName) // passing it to bind
570 | .textFieldStyle(.roundedBorder) // adds border
571 |
572 | ```
573 |
574 | Screenshot
575 |
576 |
577 | 
578 |
579 |
580 |
581 |
582 | To create secure TextField
583 |
584 | ``` swift
585 | @State var password: String = "" // create State
586 |
587 | SecureField($password) // passing it to bind
588 | .textFieldStyle(.roundedBorder) // adds border
589 |
590 | ```
591 |
592 | Screenshot
593 |
594 |
595 | 
596 |
597 |
598 |
599 |
600 | ### Slider
601 |
602 | ``` swift
603 | @State var value: Double = 0 // create State
604 |
605 | Slider(value: $value, from: -100, through: 100, by: 1)
606 | ```
607 |
608 | Screenshot
609 |
610 |
611 | 
612 |
613 |
614 |
615 |
616 | ### Date Picker
617 |
618 | ``` swift
619 | @State var selectedDate = Date()
620 | DatePicker(
621 | $selectedDate,
622 | maximumDate: Date(),
623 | displayedComponents: .date
624 | )
625 | ```
626 |
627 | Screenshot
628 |
629 |
630 | 
631 |
632 |
633 |
634 |
635 | ### Picker
636 |
637 | ``` swift
638 | @State var favoriteColor = 0
639 | var colors = ["Red", "Green", "Blue"]
640 |
641 | Picker("Favorite Color", selection: $favoriteColor) {
642 | ForEach(0 ..< colors.count) { index in
643 | Text(self.colors[index])
644 | .tag(index)
645 | }
646 | }
647 | .pickerStyle(SegmentedPickerStyle())
648 | ```
649 |
650 | Screenshot
651 |
652 |
653 | 
654 |
655 |
656 |
657 |
658 | ### Stepper
659 |
660 | ``` swift
661 | @State var count:Int = 0
662 |
663 | Stepper(
664 | onIncrement: { self.count += 1 },
665 | onDecrement: { self.count -= 1 },
666 | label: { Text("Count is \(count)") }
667 | )
668 | ```
669 |
670 | or
671 |
672 | ``` swift
673 | @State var count:Int = 0
674 |
675 | Stepper(value: $count, in: 1...10) {
676 | Text("Count is \(count)")
677 | }
678 | ```
679 | or
680 |
681 | ``` swift
682 | @State private var temperature = 0.0
683 |
684 | Stepper(value: $temperature, in: 0...100.0, step: 0.5) {
685 | Text("Temperature is \(temperature, specifier:"%g")")
686 | }
687 | ```
688 |
689 | ### Tap
690 | For single tap
691 |
692 | ``` swift
693 | Text("Tap me!")
694 | .onTapGesture {
695 | print("Tapped!")
696 | }
697 | ```
698 | For double tap
699 |
700 | ``` swift
701 | Text("Tap me!")
702 | .onTapGesture(count: 2) {
703 | print("Tapped!")
704 | }
705 | ```
706 |
707 | Screenshot
708 |
709 |
710 | 
711 |
712 |
713 |
714 |
715 | ### Gesture
716 | Gesture like **TapGesture**, **LongPressGesture**, **DragGesture**
717 |
718 | ``` swift
719 | Text("Tap")
720 | .gesture(
721 | TapGesture()
722 | .onEnded { _ in
723 | // do something
724 | }
725 | )
726 |
727 | Text("Drag Me")
728 | .gesture(
729 | DragGesture(minimumDistance: 50)
730 | .onEnded { _ in
731 | // do something
732 | }
733 | )
734 |
735 | Text("Long Press")
736 | .gesture(
737 | LongPressGesture(minimumDuration: 2)
738 | .onEnded { _ in
739 | // do something
740 | }
741 | )
742 | ```
743 |
744 | ### OnChange
745 |
746 | onChange is a new view modifier that’s available across all SwiftUI views. It lets you listen to state changes and perform actions on a view accordingly.
747 |
748 | ``` swift
749 |
750 | TextEditor(text: $currentText)
751 | .onChange(of: clearText) { value in
752 | if clearText{
753 | currentText = ""
754 | }
755 | }
756 |
757 | ```
758 |
759 | # List
760 |
761 | To create static scrollable **List**
762 |
763 | ``` swift
764 | List {
765 | Text("Hello world")
766 | Text("Hello world")
767 | Text("Hello world")
768 | }
769 | ```
770 |
771 | Screenshot
772 |
773 |
774 | 
775 |
776 |
777 |
778 |
779 | To create dynamic **List**
780 | ``` swift
781 | let names = ["Thanos", "Iron man", "Ant man"]
782 | List(names, id: \.self) { name in
783 | Text(name)
784 | }
785 | ```
786 |
787 | To add section
788 |
789 | ``` swift
790 | List {
791 | Section(header: Text("Good Hero")) {
792 | Text("Thanos")
793 | }
794 |
795 | Section(header: Text("Bad Heros")) {
796 | Text("Iron man")
797 | }
798 | }
799 | ```
800 |
801 | Screenshot
802 |
803 |
804 | 
805 |
806 |
807 |
808 |
809 | To make it grouped add *.listStyle(GroupedListStyle())*
810 |
811 | ``` swift
812 | List {
813 | Section(header: Text("Good Hero")) {
814 | Text("Thanos")
815 | }
816 |
817 | Section(header: Text("Bad Heros")) {
818 | Text("Iron man")
819 | }
820 | }.listStyle(GroupedListStyle())
821 | ```
822 |
823 | Screenshot
824 |
825 |
826 | 
827 |
828 |
829 |
830 |
831 | To add a footer to a section
832 |
833 | ``` swift
834 | List {
835 | Section(header: Text("Good Heros"), footer: Text("Powerful")){
836 | Text("Thanos")
837 | }
838 | Section(header: Text("Bad Heros"), footer: Text("Not as Powerful")){
839 | Text("Iron Man")
840 | }
841 | }.listStyle(GroupedListStyle())
842 | ```
843 |
844 | Screenshot
845 |
846 |
847 | 
848 |
849 |
850 |
851 |
852 | # Containers
853 |
854 | ### NavigationView
855 |
856 | **NavigationView** is more/less like **UINavigationController**, It handles navigation between views, shows title, places navigation bar on top.
857 |
858 | ``` swift
859 | NavigationView {
860 | Text("Hello")
861 | .navigationBarTitle(Text("World"), displayMode: .inline)
862 | }
863 | ```
864 |
865 | Screenshot
866 |
867 |
868 | 
869 |
870 |
871 |
872 |
873 | For large title use *.large*
874 |
875 | Add bar items to **NavigationView**
876 |
877 | ``` swift
878 | NavigationView {
879 | Text("Hello")
880 | .navigationBarTitle(Text("World"), displayMode: .inline)
881 | .navigationBarItems(
882 | trailing:
883 | Button(
884 | action: { print("Going to Setting") },
885 | label: { Text("Setting") }
886 | )
887 | )
888 | }
889 | ```
890 |
891 | Screenshot
892 |
893 |
894 | 
895 |
896 |
897 |
898 |
899 | ### TabView
900 |
901 | **TabView** creates a container similar to **UITabBarController** with radio-style selection control which determines which `View` is presented.
902 |
903 | ``` swift
904 | @State private var selection = 0
905 |
906 | TabView(selection: $selection) {
907 | Text("View A")
908 | .font(.title)
909 | .tabItemLabel(Text("View A")
910 | .font(.caption))
911 | .tag(0)
912 | Text("View B")
913 | .font(.title)
914 | .tabItemLabel(Text("View B")
915 | .font(.caption))
916 | .tag(1)
917 | Text("View C")
918 | .font(.title)
919 | .tabItemLabel(Text("View C")
920 | .font(.caption))
921 | .tag(2)
922 | }
923 | ```
924 |
925 | Screenshot
926 |
927 |
928 | 
929 |
930 |
931 |
932 |
933 | ### Group
934 | Group creates several views to act as one, also to avoid Stack's 10 View maximum limit.
935 |
936 | ``` swift
937 | VStack {
938 | Group {
939 | Text("Hello")
940 | Text("Hello")
941 | Text("Hello")
942 | }
943 | Group {
944 | Text("Hello")
945 | Text("Hello")
946 | }
947 | }
948 | ```
949 |
950 | Screenshot
951 |
952 |
953 | 
954 |
955 |
956 |
957 |
958 | # Alerts and Action Sheets
959 | To Show an Alert
960 |
961 | ``` swift
962 | Alert(
963 | title: Text("Title"),
964 | message: Text("message"),
965 | dismissButton: .default(Text("Ok!"))
966 | )
967 |
968 | ```
969 | To Show Action Sheet
970 |
971 | ``` swift
972 | ActionSheet(
973 | title: Text("Title"),
974 | message: Text("Message"),
975 | buttons: [
976 | .default(Text("Ok!"), action: { print("hello") })
977 | ]
978 | )
979 | ```
980 |
981 | # Navigation
982 | Navigate via **NavigationLink**
983 |
984 | ``` swift
985 | NavigationView {
986 | NavigationLink(destination: SecondView()) {
987 | Text("Show")
988 | }.navigationBarTitle(Text("First View"))
989 | }
990 | ```
991 |
992 | Screenshot
993 |
994 |
995 | 
996 |
997 |
998 |
999 |
1000 | Navigate via tap on List Item
1001 |
1002 | ``` swift
1003 | let names = ["Thanos", "Iron man", "Ant man"]
1004 | List(names, id: \.self) { name in
1005 | NavigationLink(destination: HeroView(name: name)) {
1006 | Text(name)
1007 | }
1008 | }
1009 | ```
1010 |
1011 | # Work with UIKit
1012 |
1013 | ### Navigate to ViewController
1014 |
1015 | > It's possible to work with UIKit components from SwiftUI or call SwiftUI views as View Controllers from UIKit.
1016 |
1017 | Let's say you have a View Controller named SuperVillainViewController and want to call it from a SwiftUI view, to do that ViewController needs to implement UIViewControllerRepresentable:
1018 |
1019 | ``` swift
1020 | struct SuperVillainViewController: UIViewControllerRepresentable {
1021 | var controllers: [UIViewController]
1022 | func makeUIViewcontroller(context: Context) -> SuperVillainViewController {
1023 | // you could have a custom constructor here, I'm just keeping it simple
1024 | let vc = SuperVillainViewController()
1025 | return vc
1026 | }
1027 | }
1028 | ```
1029 | Now you can use it like
1030 |
1031 | ``` swift
1032 | NavigationLink(destination: SuperVillainViewController()) {
1033 | Text("Click")
1034 | }
1035 | ```
1036 | ### Use UIKit and SwiftUI Views Together
1037 |
1038 | > To use UIView subclasses from within SwiftUI, you wrap the other view in a SwiftUI view that conforms to the UIViewRepresentable protocol. ([Reference](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views#use-uikit-and-swiftui-views-together))
1039 |
1040 | as example
1041 |
1042 | ``` swift
1043 |
1044 | import SwiftUI
1045 | import MapKit
1046 |
1047 | struct MapView: UIViewRepresentable {
1048 | func makeUIView(context: Context) -> MKMapView {
1049 | MKMapView(frame: .zero)
1050 | }
1051 |
1052 | func updateUIView(_ view: MKMapView, context: Context) {
1053 | let coordinate = CLLocationCoordinate2D(
1054 | latitude: 34.011286,
1055 | longitude: -116.166868
1056 | )
1057 | let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
1058 | let region = MKCoordinateRegion(center: coordinate, span: span)
1059 | view.setRegion(region, animated: true)
1060 | }
1061 | }
1062 |
1063 | struct MapView_Preview: PreviewProvider {
1064 | static var previews: some View {
1065 | MapView()
1066 | }
1067 | }
1068 |
1069 | ```
1070 | [](https://github.com/giridharan-dev/SwiftUi-GiSheet/stargazers)
1071 |
1072 | Thank you for all the people who starred this repo!!
1073 |
1074 |
1075 | [⏫ Top](#table-of-contents)
1076 |
--------------------------------------------------------------------------------