iOS14で簡単になった「追加読み込み」
iOS14で追加されたLazyVStack
, LazyHStack
を使うと、iOS13ではできなかったSwiftUIによる「追加読み込み」機能が簡単に実現できます。
iOS13では、UITableViewを使って実現する方法しかありませんでした。
ポイント
- LazyVStackを使い、アイテムの表示領域と、一番下に追加読み込み中のViewを配置します
- 追加読み込み中Viewの
onAppear
を使い、追加読み込みをトリガーします
ソース
View
struct ContentView: View {
@ObservedObject var viewModel: ViewModel = .init()
var body: some View {
ScrollView {
LazyVStack {
//アイテム表示領域
ForEach.init(self.viewModel.items, id: \.self) { value in
Text(value)
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(Color.init(white: 0.9).clipShape(RoundedRectangle(cornerRadius: 8))
.shadow(radius: 4))
.padding(4)
}
if self.viewModel.canLoadMore { //さらに読み込める時、表示する
Text("Loading ...")
.padding()
.onAppear {
debugPrint("onAppear")
self.viewModel.loadMore() //このViewが表示された時、追加読み込みをトリガー
}
}
}
}
}
}
ViewModel
class ViewModel: ObservableObject {
@Published var items: [String] = [] //アイテム表示用の情報
private let max: Int = 100 //最大アイテム数
private let countPerPage: Int = 20 //ページあたりのアイテム数
init() {
items = (0..<countPerPage).map({ "Item : \($0+1)" })
debugPrint(items)
}
}
extension ViewModel {
/// さらに読み込めるかどうか
var canLoadMore: Bool {
return items.count < max
}
/// さらに読み込み処理
func loadMore() {
//通信的な感じを出すため、1秒後に追加を実行
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
self?.appendItems() //アイテムを20個追加
}
}
}
.....
スクリーンショット
最後の「Loading ...」が表示されてから1秒後に、アイテムが20個ずつ追加されます。
参考
https://developer.apple.com/documentation/swiftui/lazyvstack
https://developer.apple.com/documentation/swiftui/list/onappear(perform:)
https://www.donnywals.com/implementing-an-infinite-scrolling-list-with-swiftui-and-combine/