└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # SwiftUI-Controls 2 | - [Segment](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#segment) 3 | - [Text and TabView](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#text-and-tabview) 4 | - [Stepper](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#stepper) 5 | - [Slider](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#slider) 6 | - [Date Picker](https://github.com/arjun011/SwiftUI-DatePicker) 7 | - [UIButton](https://github.com/arjun011/SwiftUI-Button) 8 | - [Form](https://github.com/arjun011/SwiftUI-Form) 9 | 10 | # SwiftUI-Views 11 | - [Circle](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#circle-shape) 12 | - [Ellipse](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#ellipse) 13 | - [Trim Circle](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#circle-trim-shape) 14 | - [ActionSheet with isPresented](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#action-sheet-with-ispresented) 15 | - [ActionSheet with item](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#actionsheet-with-item) 16 | - [contextMenu](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#contextmenu) 17 | - [Offset](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#offset) 18 | - [Mask](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#mask) 19 | - [Rotation](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#rotation) 20 | - [LayOut Priority](https://github.com/arjun011/SwiftUI-Controls/blob/master/README.md#layout-priority) 21 | - [LazyHGrid](https://github.com/arjun011/LazyHGrid) 22 | 23 | ## Segment 24 | 25 | struct ContentView: View { 26 | @State private var dayNight = "morning" 27 | @State private var tab = 0 28 | @State private var meals = "one" 29 | 30 | var body: some View { 31 | VStack(spacing: 20){ 32 | Text("Segment") 33 | .font(.largeTitle) 34 | Picker(selection: $dayNight, label: Text("DayPiker")) { 35 | Text("Morning").tag("morning") 36 | Text("Noon").tag("noon") 37 | Text("Night").tag("night") 38 | }.labelsHidden() 39 | .pickerStyle(SegmentedPickerStyle()) 40 | 41 | Picker(selection: $tab, label: Text("")) { 42 | Image(systemName: "sun.min").tag(0) 43 | Image(systemName: "moon").tag(1) 44 | }.pickerStyle(SegmentedPickerStyle()) 45 | 46 | Picker(selection: $meals, label: Text("")) { 47 | Text("One").tag("one") 48 | Text("Two").tag("two") 49 | Text("Three").tag("three") 50 | Text("More").tag("more") 51 | } 52 | .background(Color.yellow) 53 | .cornerRadius(10) 54 | .padding(.horizontal) 55 | .pickerStyle(SegmentedPickerStyle()) 56 | 57 | 58 | Spacer() 59 | }.padding() 60 | } 61 | } 62 | 63 | ### Output 64 | 65 | ![Screenshot 2020-02-18 at 1 58 39 PM](https://user-images.githubusercontent.com/16661905/74718519-67c84800-5258-11ea-90d0-78b60002ff92.png) 66 | 67 | ## Text and TabView 68 | 69 | struct FontDesign: View { 70 | var body: some View { 71 | NavigationView { 72 | VStack(spacing: 10) { 73 | Text("Default font design") 74 | .font(Font.system(size:30, design: .default)) 75 | Divider() 76 | Text("Monospaced font design") 77 | .font(Font.system(size:30, design: .monospaced)) 78 | Divider() 79 | Text("Rounded font design") 80 | .font(Font.system(size:30, design: .rounded)) 81 | Divider() 82 | Text("Serif font design") 83 | .font(Font.system(size:30, design: .serif)) 84 | Divider() 85 | 86 | .navigationBarTitle(Text("Design")) 87 | }.padding() 88 | } 89 | } 90 | } 91 | 92 | struct TextStyle: View { 93 | var body: some View { 94 | NavigationView { 95 | VStack(spacing:10) { 96 | Text("Large Title").font(.largeTitle) 97 | Text("Title").font(.title) 98 | Text("Headline").font(.headline) 99 | Text("SubHeadline").font(.subheadline) 100 | Text("Body").font(.body) 101 | Text("Callout").font(.callout) 102 | Text("Caption").font(.caption) 103 | Text("FootNote").font(.footnote) 104 | } 105 | .navigationBarTitle(Text("Text Styles")) 106 | } 107 | } 108 | } 109 | 110 | struct WeightStyle: View { 111 | var body: some View { 112 | NavigationView { 113 | VStack(spacing:10) { 114 | Text("Ultralight").fontWeight(.ultraLight) 115 | Text("Thin").fontWeight(.thin) 116 | Text("Light").fontWeight(.light) 117 | Text("Regular").fontWeight(.regular) 118 | Text("Medium").fontWeight(.medium) 119 | Text("SemiBold").fontWeight(.semibold) 120 | Text("Bold").fontWeight(.bold) 121 | VStack(spacing:10) { 122 | Text("Heavy").fontWeight(.heavy) 123 | Text("Black").fontWeight(.black) 124 | } 125 | } 126 | .navigationBarTitle(Text("Weight")) 127 | } 128 | } 129 | } 130 | 131 | 132 | struct ContentView: View { 133 | @State var selectedTab = 0 134 | var body: some View { 135 | TabView(selection:$selectedTab) { 136 | TextStyle().tabItem { 137 | Image(systemName: "textformat") 138 | Text("Styles") 139 | }.tag(0) 140 | WeightStyle().tabItem { 141 | Image(systemName: "bold") 142 | Text("Weight") 143 | }.tag(1) 144 | FontDesign().tabItem { 145 | Image(systemName: "text.cursor") 146 | Text("Design") 147 | }.tag(2) 148 | } 149 | } 150 | } 151 | 152 | ### OutPut 153 | 154 | ![Screenshot 2020-02-18 at 2 32 03 PM](https://user-images.githubusercontent.com/16661905/74720699-2e91d700-525c-11ea-842c-e1a0d233f238.png) 155 | ![Screenshot 2020-02-18 at 2 31 56 PM](https://user-images.githubusercontent.com/16661905/74720701-305b9a80-525c-11ea-93e8-4e6d61e97259.png) 156 | ![Screenshot 2020-02-18 at 2 31 44 PM](https://user-images.githubusercontent.com/16661905/74720702-30f43100-525c-11ea-8786-32b44d82e125.png) 157 | 158 | ## Stepper 159 | 160 | struct ContentView: View { 161 | @State private var stepperValue = 1 162 | @State private var values = [0,1] 163 | var body: some View { 164 | VStack(spacing:20) { 165 | Text("Stepper") 166 | .font(.largeTitle) 167 | Stepper(value: $stepperValue) { 168 | Text("Bound Stepper: \(stepperValue)") 169 | } 170 | 171 | Stepper(onIncrement: { 172 | self.values.append(self.values.count) 173 | }, onDecrement: { 174 | self.values.removeLast() 175 | }) { 176 | Text("OnIncrement and OnDecrement") 177 | } 178 | ScrollView(.horizontal) { 179 | HStack { 180 | ForEach(values, id: \.self) { value in 181 | Image(systemName: "\(value).circle.fill").font(.largeTitle) 182 | .foregroundColor(.green) 183 | } 184 | }.padding() 185 | } 186 | Stepper(value: $stepperValue, in: 1...5) { 187 | Text("Rating") 188 | }.padding(.horizontal) 189 | HStack { 190 | ForEach(1...stepperValue, id: \.self) { star in 191 | Image(systemName: "star.fill") 192 | .foregroundColor(.yellow) 193 | } 194 | } 195 | }.padding() 196 | } 197 | } 198 | 199 | ### OutPut 200 | 201 | ![Screenshot 2020-02-18 at 2 48 46 PM](https://user-images.githubusercontent.com/16661905/74721993-32bef400-525e-11ea-9d00-7f4e57aa34e6.png) 202 | 203 | ## Slider 204 | 205 | struct ContentView: View { 206 | @State private var age = 18.0 207 | @State private var sliderValue = 0.3 208 | let ageFormatter: NumberFormatter = { 209 | let numFormate = NumberFormatter() 210 | numFormate.numberStyle = .spellOut 211 | return numFormate 212 | }() 213 | var body: some View { 214 | VStack(spacing:20){ 215 | Text("Slider") 216 | Slider(value: $age, in: 1...100, step: 1) 217 | Group { 218 | Text("Age: ") + Text("\(ageFormatter.string(from: NSNumber(value: age))!)").foregroundColor(.green) 219 | } 220 | 221 | Slider(value: $sliderValue) 222 | .padding(.horizontal) 223 | .background(Color.yellow) 224 | .cornerRadius(10) 225 | .shadow(color: .gray, radius: 5) 226 | .accentColor(Color.green) 227 | 228 | Slider(value: $sliderValue) 229 | .padding(.horizontal) 230 | .background(Capsule().stroke(Color.orange, lineWidth: 2)) 231 | .accentColor(.orange) 232 | 233 | Slider(value:$sliderValue) 234 | .padding(.horizontal) 235 | .background(Capsule().fill(Color.yellow)) 236 | .accentColor(.black) 237 | 238 | HStack { 239 | Image(systemName: "tortoise") 240 | Slider(value:$sliderValue) 241 | Image(systemName: "hare") 242 | }.padding() 243 | .foregroundColor(.green) 244 | Spacer() 245 | }.padding() 246 | } 247 | } 248 | 249 | ## OutPut 250 | 251 | ![Screenshot 2020-02-18 at 2 58 50 PM](https://user-images.githubusercontent.com/16661905/74722658-4dde3380-525f-11ea-8e4c-102cd6905bd2.png) 252 | 253 | ## Circle shape 254 | 255 | struct CircleCustomeTab: View { 256 | var body: some View { 257 | VStack(spacing: 15) { 258 | Text("Circle") 259 | Circle() 260 | .fill(Color.orange) 261 | .frame(width: 100) 262 | 263 | Circle() 264 | .stroke(Color.red, style: StrokeStyle(lineWidth: 4, dash: [9,5])) 265 | //.stroke(Color.red, lineWidth: 5) 266 | .frame(width:100) 267 | 268 | 269 | Circle() 270 | .foregroundColor(.green) 271 | .frame(width: 100) 272 | 273 | ZStack() { 274 | Circle() 275 | .stroke(Color.red,lineWidth: 10) 276 | 277 | Circle() 278 | .stroke(Color.yellow,lineWidth: 10) 279 | .padding(20) 280 | 281 | Circle() 282 | .stroke(Color.black,lineWidth: 10) 283 | .padding(40) 284 | 285 | Circle() 286 | .stroke(Color.purple,lineWidth: 10) 287 | .padding(60) 288 | 289 | 290 | }.frame(width:200, height:200) 291 | 292 | ZStack { 293 | Circle() 294 | .fill(Color.secondary) 295 | .frame(height:250) 296 | Circle() 297 | .fill(Color.secondary) 298 | .frame(height:200) 299 | Circle() 300 | .fill(Color.secondary) 301 | .frame(height:150) 302 | Circle() 303 | .fill(Color.secondary) 304 | .frame(height:100) 305 | } 306 | 307 | }.padding() 308 | } 309 | } 310 | 311 | ### OutPut 312 | 313 | ![Screenshot 2020-02-19 at 6 14 57 PM](https://user-images.githubusercontent.com/16661905/74835850-3b89f580-5344-11ea-8357-448978192438.png) 314 | 315 | ### Ellipse 316 | 317 | struct EllipeCustomView: View { 318 | var body: some View { 319 | VStack(spacing:20) { 320 | Text("Ellips") 321 | Ellipse() 322 | 323 | ZStack { 324 | Ellipse() 325 | .stroke(Color.yellow, lineWidth: 30) 326 | Ellipse() 327 | .stroke() 328 | }.padding() 329 | 330 | ZStack { 331 | Ellipse() 332 | .strokeBorder(Color.pink,lineWidth: 30) 333 | Ellipse() 334 | .stroke() 335 | } 336 | 337 | Spacer() 338 | }.padding() 339 | } 340 | } 341 | 342 | ## OutPut 343 | 344 | ![Screenshot 2020-02-19 at 6 15 06 PM](https://user-images.githubusercontent.com/16661905/74836253-0c27b880-5345-11ea-8415-34c3e6057632.png) 345 | 346 | ## Circle Trim shape 347 | 348 | struct TripOutLine: View { 349 | @State private var orangeCircleProgress:CGFloat = 0.9 350 | @State private var greenCircleProgress:CGFloat = 0.3 351 | private var percentage:Int { 352 | get { 353 | return Int(orangeCircleProgress * 100.0) 354 | } 355 | } 356 | var body: some View { 357 | VStack { 358 | Text("Circle Shape") 359 | .font(.largeTitle) 360 | Text("Trim function") 361 | .foregroundColor(.gray) 362 | 363 | ZStack { 364 | Circle() 365 | .trim(from: 0.0, to: orangeCircleProgress) 366 | .stroke(Color.orange, style: StrokeStyle(lineWidth: 40, lineCap: CGLineCap.round)) 367 | .frame(width:300) 368 | .rotationEffect(.degrees(-90)) 369 | .overlay( 370 | Text("\(percentage)%") 371 | ) 372 | 373 | Circle() 374 | .trim(from: 0.0, to: greenCircleProgress) 375 | .stroke(Color.green, style: StrokeStyle(lineWidth: 40, lineCap: CGLineCap.round)) 376 | .frame(width:170) 377 | .rotationEffect(.degrees(-90)) 378 | .overlay( 379 | Text("\(percentage)%") 380 | ) 381 | } 382 | .padding() 383 | Text("Completed Circle") 384 | Slider(value: $orangeCircleProgress) 385 | .padding(.horizontal) 386 | .accentColor(.orange) 387 | 388 | Slider(value: $greenCircleProgress) 389 | .padding(.horizontal) 390 | .accentColor(.green) 391 | 392 | }.font(.title) 393 | .padding() 394 | } 395 | } 396 | 397 | ### OutPut 398 | 399 | ![Screenshot 2020-02-19 at 6 14 52 PM](https://user-images.githubusercontent.com/16661905/74838668-fd8fd000-5349-11ea-864b-1226ead4efeb.png) 400 | 401 | ## Action Sheet with isPresented 402 | 403 | struct ContentView: View { 404 | @State private var openActionsheet:Bool = false 405 | var body: some View { 406 | VStack(spacing:20) { 407 | Text("Action Sheet") 408 | Button(action: { 409 | self.openActionsheet = true 410 | }) { 411 | Text("Open Action Sheet") 412 | } 413 | }.actionSheet(isPresented: $openActionsheet) { () -> ActionSheet in 414 | ActionSheet(title: Text("Hello!"), message: Text("This is action sheet."), buttons: [ 415 | .default(Text("Action1"), action: { 416 | // Action 1 417 | }), 418 | .default(Text("Action2"), action: { 419 | // Action 2 420 | }), 421 | .destructive(Text("Red"), action: { 422 | // Action 3 423 | }), 424 | .cancel({ 425 | // Cancel 426 | }) 427 | ]) 428 | } 429 | } 430 | } 431 | 432 | ### OutPut 433 | 434 | ![Screenshot 2020-02-24 at 5 25 29 PM](https://user-images.githubusercontent.com/16661905/75150839-49b48900-572b-11ea-8a31-7436fc539017.png) 435 | 436 | ## ActionSheet with item 437 | 438 | // Create Identifiable struct to hold action sheet data. 439 | struct ActionSheetData:Identifiable { 440 | var id = UUID() 441 | var title:String 442 | var message:String 443 | } 444 | struct customDataAction: View { 445 | @State private var actionSheetData: ActionSheetData? = nil 446 | var body: some View { 447 | VStack(spacing:20) { 448 | Text("Action Sheet") 449 | .font(.largeTitle) 450 | Text("Action with custom data") 451 | .foregroundColor(.gray) 452 | Button(action: { 453 | self.actionSheetData = ActionSheetData(title: "Save", message: "Choose an option!") 454 | }) { 455 | Text("Open Action sheet") 456 | } 457 | }.actionSheet(item: $actionSheetData) { sheetData in 458 | ActionSheet(title: Text(sheetData.title), message: Text(sheetData.message), buttons: [ 459 | .default(Text("Default Option"), action: { 460 | //Option 1 461 | }), 462 | .destructive(Text("Destructive Option"), action: { 463 | // Destructive option 464 | }), 465 | .cancel({ 466 | // Cancel 467 | }) 468 | ]) 469 | } 470 | } 471 | } 472 | 473 | ### OutPut 474 | 475 | ![Screenshot 2020-02-24 at 5 25 58 PM](https://user-images.githubusercontent.com/16661905/75153089-80d96900-5730-11ea-873e-9b90c1f05dac.png) 476 | 477 | ## ContextMenu 478 | 479 | struct ContentView: View { 480 | var body: some View { 481 | VStack(spacing:10) { 482 | Text("Context Menu") 483 | .font(.largeTitle) 484 | Text("Introduction") 485 | .foregroundColor(.gray) 486 | Spacer() 487 | HStack() { 488 | Text("Get Help") 489 | Spacer() 490 | Image(systemName: "questionmark.diamond.fill") 491 | .foregroundColor(.yellow) 492 | .contextMenu { 493 | Button(action: {}) { 494 | Image(systemName: "eyedropper.full") 495 | Text("Add Color") 496 | } 497 | Button(action: {}) { 498 | Image(systemName: "sun.haze") 499 | Text("Haze") 500 | } 501 | Button(action: {}) { 502 | Image(systemName: "circle.lefthalf.fill") 503 | Text("Change Constrast") 504 | } 505 | } 506 | }.padding() 507 | Spacer() 508 | }.font(.title) 509 | } 510 | } 511 | 512 | ### OutPut 513 | 514 | ![Screenshot 2020-03-05 at 1 38 47 PM](https://user-images.githubusercontent.com/16661905/75962635-26879780-5eea-11ea-8258-012a563691aa.png) 515 | 516 | ## Offset 517 | 518 | VStack(spacing: 20) { 519 | Text("Offset") 520 | .font(.largeTitle) 521 | ZStack { 522 | RoundedRectangle(cornerRadius: 10) 523 | .frame(width: 200, height: 100) 524 | .foregroundColor(.green) 525 | .shadow(radius: 5) 526 | .offset(x: -20, y: -10) 527 | 528 | RoundedRectangle(cornerRadius: 10) 529 | .frame(width: 200, height: 100) 530 | .foregroundColor(.blue) 531 | .shadow(radius: 5) 532 | 533 | RoundedRectangle(cornerRadius: 10) 534 | .frame(width: 200, height: 100) 535 | .foregroundColor(.red) 536 | .shadow(radius: 5) 537 | .offset(x: 20, y: 20) 538 | 539 | } 540 | } 541 | 542 | ### Output 543 | 544 | ![Screenshot 2020-03-11 at 6 08 08 PM](https://user-images.githubusercontent.com/16661905/76417878-acf91900-63c3-11ea-8c0e-995368251cfe.png) 545 | 546 | ## Mask 547 | 548 | struct ContentView: View { 549 | var body: some View { 550 | VStack { 551 | Text("Mask") 552 | .font(.largeTitle) 553 | Text("Mask is use to cut out background with other view ") 554 | .padding() 555 | .frame(maxWidth: .infinity) 556 | .background(Color.orange) 557 | 558 | Image("Flag-India") 559 | .resizable() 560 | .scaledToFill() 561 | .frame(width: 100, height: 100) 562 | .mask(Circle()) 563 | 564 | Image("images") 565 | .resizable() 566 | .frame(width: 100, height: 100) 567 | .mask( 568 | Text("INDIA") 569 | .fontWeight(.black) 570 | .font(.largeTitle) 571 | ) 572 | Image("images") 573 | .resizable() 574 | .frame(width: 100, height: 100) 575 | .mask(Image(systemName: "tortoise").resizable()) 576 | Spacer() 577 | 578 | } 579 | } 580 | } 581 | 582 | ### Output 583 | 584 | ![Screen Shot 2020-04-23 at 1 53 55 PM](https://user-images.githubusercontent.com/16661905/80076597-1004d080-856a-11ea-94b0-479c89c84d73.png) 585 | 586 | ## Rotation 587 | struct ContentView: View { 588 | @State var degree:Double = 360 589 | var body: some View { 590 | 591 | VStack(spacing: 30) { 592 | Text("Rotation") 593 | .font(.largeTitle) 594 | HStack { 595 | Text("45") 596 | .rotationEffect(Angle.degrees(45)) 597 | Text("-45") 598 | .rotationEffect(Angle.degrees(-45)) 599 | Text("90") 600 | .rotationEffect(Angle.degrees(90)) 601 | Text("180") 602 | .rotationEffect(Angle.degrees(180)) 603 | Text("270") 604 | .rotationEffect(Angle.degrees(270)) 605 | Text("360") 606 | .rotationEffect(Angle.degrees(360)) 607 | } 608 | Spacer() 609 | 610 | Text("Rotation") 611 | .font(.caption) 612 | .padding() 613 | .rotationEffect(Angle.degrees(degree)) 614 | .border(Color.orange) 615 | 616 | HStack { 617 | Text("Top Rotation") 618 | .font(.caption) 619 | .padding() 620 | .rotationEffect(Angle.degrees(degree), anchor: .top) 621 | .border(Color.orange) 622 | 623 | Text("TopLeading Rotation") 624 | .font(.caption) 625 | .padding() 626 | .rotationEffect(Angle.degrees(degree), anchor: .topLeading) 627 | .border(Color.orange) 628 | } 629 | 630 | HStack { 631 | Text("Bottom Rotation") 632 | .font(.caption) 633 | .padding() 634 | .rotationEffect(Angle.degrees(degree), anchor: .bottom) 635 | .border(Color.orange) 636 | 637 | Text("BottomLeading Rotation") 638 | .font(.caption) 639 | .padding() 640 | .rotationEffect(Angle.degrees(degree), anchor: .bottomLeading) 641 | .border(Color.orange) 642 | } 643 | 644 | Slider(value: $degree, in: 0...360, step: 5.0) 645 | .padding() 646 | Text("\(degree, specifier: "%.2f") Degree") 647 | Spacer() 648 | } 649 | } 650 | } 651 | 652 | ### Output 653 | 654 | ![Screenshot 2020-04-24 at 10 49 45 AM](https://user-images.githubusercontent.com/16661905/80177448-6bda6280-8619-11ea-8c93-1b4dd19a51ab.png) 655 | 656 | ## Layout Priority 657 | default value is 0 658 | .layoutPriority(0) 659 | 660 | struct ContentView: View { 661 | var body: some View { 662 | HStack(alignment: .center, content: { 663 | Text("Hello World") 664 | Text("SwiftUI") 665 | .foregroundColor(.blue) 666 | Text("It's a next future") 667 | .layoutPriority(1) 668 | }).font(.title) 669 | .lineLimit(1) 670 | } 671 | } 672 | ### Output 673 | 674 | Screenshot 2021-10-18 at 2 26 31 PM 675 | 676 | 677 | 678 | --------------------------------------------------------------------------------