3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[iOS14]SwiftUIで追加読み込み

Posted at

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/

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?