SwiftUI: List or LazyVStack? đ€SwipeActions for any views?
List or LazyVStack? Which one is best to use and when?
It depends, of coz, on the task. For example, if the app based on on UIKit, and you want to add SwiftUI, then you should be considered that the separators between cells in the List, if they are not needed, are removed in a very âcrutchâ way before iOS 15:
.onAppear {
UITableView.appearance().separatorStyle = .none
}
This can affect the design of the UITableView throughout the whole application. Beginning with iOS 15 a special modifier .listRowSeparator(.hidden)
has already appeared for this.
One of the main key features is the difference in the rendering (which depend on iOS versions) of List and LazyVStack. In iOS < 15 List renders cells âwith a marginâ, namely, if the List is stretched to full screen, then the first 15 (iPhone 6s) â 20 elements do not have lazy loading, and it doesnât matter what the elementâs frame height is. Opp, LazyVStack renders only elements that are visible on the screen. Thus, for example, by setting the .onAppear{âŠ} modifier, we get the expected behavior only for LazyVStack.
Beginning with iOS 15 List renders only items that are visible on the screen. Turns out that in iOS < 15 using List pagination can only be done if you should load > 20 items. This may not suit for everyone and LazyVStack should be used.
The other problem for List is that cells are really slightly customizable. Even so List has a big advantage in swipeActions. Actually this method is available from iOS 15. But is it possible to get power of swipeActions for LazyVStack cells? Yep, sure, and not only for LazyVStack but even for any view! You can simply use this package! Moreover you can use it in project targeting iOS 13. Quick start is here.
The process for adding SwipeActions
is quite simple so Iâll just provide an example of the code:
import SwipeActions
struct YourView: View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(1...100, id: \.self) { cell in
Text("Cell \(cell)")
.frame(height: 50, alignment: .center)
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
.addSwipeAction(edge: .trailing) { // đđ» LOOK HERE
Button {
print("remove \(cell)")
} label: {
Image(systemName: "trash")
.foregroundColor(.white)
}
.frame(width: 60, height: 50, alignment: .center)
.contentShape(Rectangle())
.background(Color.red)
Button {
print("Inform \(cell)")
} label: {
Image(systemName: "bell.slash.fill")
.foregroundColor(.white)
}
.frame(width: 60, height: 50, alignment: .center)
.background(Color.blue)
}
}
}
}
}
}
The result will be:
Thatâs all!âđ» Donât forget to subscribe me on github and to my Telegram channel dedicated to mobile development.