-
Book Overview & Buying
-
Table Of Contents
SwiftUI Cookbook
By :
SwiftUI 2.0 introduced the LazyHStack and LazyVStack components. These components are used in a similar way to regular HStack and VStack components but offer the advantage of lazy loading. Lazy components are loaded just before the item becomes visible on the device's screen during a device scroll, therefore reducing latency.
We will create an app that uses LazyHStack and LazyVStack and observe how it works.
Let's create a new SwiftUI app called LazyStacks:
LazyStacks in the Product Name field and select SwiftUI App from the Life Cycle field.We will implement a LazyHStack and LazyVStack view within a single SwiftUI view file by embedding both in a VStack component. The steps are as follows:
ContentView.swift file to view its content in Xcode's editor pane.ListRow SwiftUI view that will have two properties: an ID and a type. ListRow should also print a statement showing what item is currently being initialized:struct ListRow: View {
let id: Int
let type: String
init(id: Int, type: String){
print("Loading \(type) item \(id)")
self.id = id
self.type = type
}
var body: some View {
Text("\(type) \(id)").padding()
}
}Text view with VStack:VStack {
}VStack component and use a .frame() modifier to limit the view's height:ScrollView(.horizontal){
}.frame(height: 100, alignment: .center)LazyHStack inside the scroll view with a ForEach view that iterates through the numbers 1–10000 and displays them using our ListRow view:LazyHStack {
ForEach(1...10000, id:\.self){ item in
ListRow(id: item, type: "Horizontal")
}
}VStack with a LazyVStack struct that loops through numbers 1–10000:ScrollView {
LazyVStack {
ForEach(1...10000, id:\.self){ item in
ListRow(id: item, type: "Vertical")
}
}
}
Figure 2.10 – Show Debug Area

Figure 2.11 – Selecting the simulator from Xcode

Figure 2.12 – The LazyStacks app running on the simulator
LazyHStack (located at the top). Observe how the print statements appear in the debug area just before an item is displayed on the screen. Each item is initialized just before it is displayed.LazyVStack. Observe how the print statements appear in the debug area just before an item is displayed.We started this recipe by creating the ListRow view because we wanted to clearly demonstrate the advantage of lazy loading over the regular method where all items get loaded at once. The ListRow view has two properties: an ID and a string. We add a print statement to the init() function so that we can observe when each item gets initialized:
init(id: Int, type: String){
print("Loading \(type) item \(id)")
self.id = id
self.type = type
}
The ListRow view body presents a Text view with the ID and type parameters passed to it.
Moving up to the ContentView struct, we replace the initial Text view in the body variable with a VStack component. This allows us to implement both LazyHStack and LazyVStack within the same SwiftUI view.
We implement LazyHStack by first wrapping it in a scroll view, then using a ForEach struct to iterate over the range of values we want to display. For each of those values, a new ListRow view is initialized just before it becomes visible when the user scrolls down:
ScrollView {
LazyVStack {
ForEach(1...10000, id:\.self){ item in
ListRow(id: item, type: "Vertical")
}
}
}
Run the app using a device emulator to view the print statements before each item is initialized. Nothing will be printed if the app is run in live preview mode on Xcode.
Try implementing the preceding app using a regular HStack or VStack component and observe the performance difference. The app will be significantly slower since all the rows are initialized at once.