struct LazyVStackExample1: View { let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss z" return formatter }() var body: some View { ScrollView { VStack { ForEach(1...100, id: \.self) { _ in Text(Date(), formatter: dateFormatter) } } } } }
struct LazyVStackExample2: View { let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss z" return formatter }() var body: some View { ScrollView { LazyVStack { ForEach(1...100, id: \.self) { _ in Text(Date(), formatter: dateFormatter) } } } } }
struct LazyVStackExample3: View { var body: some View { VStack(spacing: 50) { Text ("VStack Example") .bold() VStack(spacing: 20) { Text("DevTechie Courses") .font(.largeTitle) Text("Video Courses on iOS") } .foregroundColor(.white) .padding() .background(RoundedRectangle(cornerRadius: 20).fill(Color.orange)) Text ("LazyVStack Example") .bold() LazyVStack(spacing: 20) { Text("DevTechie Courses") .font(.largeTitle) Text("Video Courses on iOS") } .foregroundColor(.white) .padding() .background(RoundedRectangle(cornerRadius: 20).fill(Color.orange)) } } }
struct LazyVStackExample5: View { @State private var alignmentProp: HorizontalAlignment = .center var body: some View { VStack { Text("VStack") .bold() .font(.largeTitle) VStack(alignment: alignmentProp) { Capsule() .fill(.orange) .frame(width: 100, height: 50) Capsule() .fill(.teal) .frame(width: 200, height: 50) Capsule() .fill(.mint) .frame(height: 50) } .padding() .animation(.easeInOut, value: alignmentProp) Text("LazyVStack") .bold() .font(.largeTitle) LazyVStack(alignment: alignmentProp) { Capsule() .fill(.orange) .frame(width: 50, height: 50) Capsule() .fill(.teal) .frame(width: 100, height: 50) Capsule() .fill(.mint) .frame(width: 150, height: 50) } .padding() .animation(.easeInOut, value: alignmentProp) HStack { Button("Leading") { alignmentProp = .leading } Button("Center") { alignmentProp = .center } Button("Trailing") { alignmentProp = .trailing } } } } }
Notice that in case of VStack we have to make one capsule wide enough so rest capsule views can animate to alignment changes
enum CourseCategory: String, CaseIterable { case swiftUI = "SwiftUI" case machineLearning = "Machine Learning" case iOS = "iOS" case swift = "Swift" }
struct DevTechieCourse: Identifiable { let id = UUID() var name: String var category: CourseCategory }
extension DevTechieCourse { static func getCourses(by category: CourseCategory) -> [DevTechieCourse] { sampleCourses.filter { course in course.category == category } } static var sampleCourses: [DevTechieCourse] { [ DevTechieCourse(name: "SwiftUI Deep Dive", category: .swiftUI), DevTechieCourse(name: "SwiftUI and Core Data", category: .swiftUI), DevTechieCourse(name: "Local Authentication in Swiftui", category: .swiftUI), DevTechieCourse(name: "Machine Learning in SwiftUI", category: .swiftUI), DevTechieCourse(name: "SwiftUI Deep Dive", category: .swiftUI), DevTechieCourse(name: "SwiftUI and Core Data", category: .swiftUI), DevTechieCourse(name: "Local Authentication in Swiftui", category: .swiftUI), DevTechieCourse(name: "Machine Learning in SwiftUI", category: .swiftUI), DevTechieCourse(name: "SwiftUI Deep Dive", category: .swiftUI), DevTechieCourse(name: "SwiftUI and Core Data", category: .swiftUI), DevTechieCourse(name: "Local Authentication in Swiftui", category: .swiftUI), DevTechieCourse(name: "Machine Learning in SwiftUI", category: .swiftUI), DevTechieCourse(name: "SwiftUI Deep Dive", category: .swiftUI), DevTechieCourse(name: "SwiftUI and Core Data", category: .swiftUI), DevTechieCourse(name: "Local Authentication in Swiftui", category: .swiftUI), DevTechieCourse(name: "Machine Learning in SwiftUI", category: .swiftUI), DevTechieCourse(name: "Machine Learning in iOS", category: .machineLearning), DevTechieCourse(name: "Computer Vision in iOS", category: .machineLearning), DevTechieCourse(name: "CreateML and CoreML", category: .machineLearning), DevTechieCourse(name: "Machine Learning in iOS", category: .machineLearning), DevTechieCourse(name: "Computer Vision in iOS", category: .machineLearning), DevTechieCourse(name: "CreateML and CoreML", category: .machineLearning), DevTechieCourse(name: "Machine Learning in iOS", category: .machineLearning), DevTechieCourse(name: "Computer Vision in iOS", category: .machineLearning), DevTechieCourse(name: "CreateML and CoreML", category: .machineLearning), DevTechieCourse(name: "Machine Learning in iOS", category: .machineLearning), DevTechieCourse(name: "Computer Vision in iOS", category: .machineLearning), DevTechieCourse(name: "CreateML and CoreML", category: .machineLearning), DevTechieCourse(name: "Machine Learning in iOS", category: .machineLearning), DevTechieCourse(name: "Computer Vision in iOS", category: .machineLearning), DevTechieCourse(name: "CreateML and CoreML", category: .machineLearning), DevTechieCourse(name: "iOS Development Fundamentals", category: .iOS), DevTechieCourse(name: "Protocol Oriented Programming", category: .iOS), DevTechieCourse(name: "iOS 15: What's New", category: .iOS), DevTechieCourse(name: "Codable Protocol in iOS", category: .iOS), DevTechieCourse(name: "iOS Development Fundamentals", category: .iOS), DevTechieCourse(name: "Protocol Oriented Programming", category: .iOS), DevTechieCourse(name: "iOS 15: What's New", category: .iOS), DevTechieCourse(name: "Codable Protocol in iOS", category: .iOS), DevTechieCourse(name: "iOS Development Fundamentals", category: .iOS), DevTechieCourse(name: "Protocol Oriented Programming", category: .iOS), DevTechieCourse(name: "iOS 15: What's New", category: .iOS), DevTechieCourse(name: "Codable Protocol in iOS", category: .iOS), DevTechieCourse(name: "iOS Development Fundamentals", category: .iOS), DevTechieCourse(name: "Protocol Oriented Programming", category: .iOS), DevTechieCourse(name: "iOS 15: What's New", category: .iOS), DevTechieCourse(name: "Codable Protocol in iOS", category: .iOS), DevTechieCourse(name: "Higher Order Function in Swift", category: .swift), DevTechieCourse(name: "Combine in Swift", category: .swift), DevTechieCourse(name: "Swift 5.5", category: .swift), DevTechieCourse(name: "Higher Order Function in Swift", category: .swift), DevTechieCourse(name: "Combine in Swift", category: .swift), DevTechieCourse(name: "Swift 5.5", category: .swift), DevTechieCourse(name: "Higher Order Function in Swift", category: .swift), DevTechieCourse(name: "Combine in Swift", category: .swift), DevTechieCourse(name: "Swift 5.5", category: .swift) ] } }
struct HeaderView: View { var title: String var body: some View { Text(title) .font(.largeTitle) .bold() .frame(maxWidth: .infinity, maxHeight: 50) .background(.ultraThinMaterial) } }
struct LazyVStackExample4: View { var body: some View { NavigationView { ScrollView { LazyVStack(alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) { ForEach(CourseCategory.allCases, id: \.self) { category in Section(header: HeaderView(title: category.rawValue)) { ForEach(DevTechieCourse.getCourses(by: category)) { course in Text("▶ \(course.name)") .font(.title2) .padding() } } } } } .navigationTitle("DevTechie Courses") } } }
struct FooterView: View { var title: String var body: some View { Text(title) .bold() .frame(maxWidth: .infinity) .frame(height: 50) .background(.ultraThinMaterial) } }
struct LazyVStackExample4: View { var body: some View { NavigationView { ScrollView { LazyVStack(alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders, .sectionFooters]) { ForEach(CourseCategory.allCases, id: \.self) { category in let courses = DevTechieCourse.getCourses(by: category) Section(header: HeaderView(title: category.rawValue), footer: FooterView(title: "Total \(courses.count) courses.")) { ForEach(courses) { course in Text("▶ \(course.name)") .font(.title2) .padding() } } } } } .navigationTitle("DevTechie Courses") .edgesIgnoringSafeArea(.bottom) } } }