【Swift】tableViewで無限スクロールを実装してみた

どうも、ねこきち(@nekokichi1_yos2)です。

 

今回は、tableViewで無限スクロール、を実装。

 

解説

 

仕組みは

  1. スクロール開始
  2. (num.count -10)番目の要素が表示された
  3. numにnumの全要素を追加
  4. スクロール終了

 

スクロール時のnumの要素とセルの追加処理は、willDisplaycell、で行います。

 

セルを表示する前に呼び出されるので、問題なく処理が通ります。

 

ただ、scrollViewDidScroll()内でも追加処理を実行できますが、重複して処理が行われてしまうので、推奨はされてません。

orangelog.site

 

追加処理後のリロード処理をそのまま実行しても、スクロール動作と追加処理が原因なのか、少し動作がもっさりします。

 

しかし、DispatchQueueでメインスレッドに登録すれば、スムーズに動作します。

stackoverflow.com

 

ちなみに、途中でnumの要素を一部削除しようとしても、cellForRowAtでエラーが出る..。なんでだろう..。

 

ソースコード

 

import UIKit

class InfiniteScroll_tableView: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
    @IBOutlet weak var tableView: UITableView!
    
    var num = [String]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        //1~20の数字を代入
        for i in 1...10 {
            num.append("\(i)")
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return num.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel!.text = num[indexPath.row]
        return cell
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        //メインスレッドでtableViewを更新
        DispatchQueue.main.async {
            if indexPath.row == self.num.count - 10 {
                self.num.append(contentsOf: self.num)
                tableView.reloadData()
            }
        }
    }
    
}

 

結果