Tableviewには、無限のスクロール/ページネーションを追加する組み込み関数があるのでしょうか。
現在、私のVCは次のようになります。
var data: JSON! = []
override func viewDidLoad() {
super.viewDidLoad()
//Init start height of cell
self.tableView.estimatedRowHeight = 122
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.delegate = self
self.tableView.dataSource = self
savedLoader.startAnimation()
//Load first page
loadSaved(1)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("aCell") as! SavedTableViewCell
let info = data[indexPath.row]
cell.configureWithData(info)
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("WebSegue", sender: indexPath)
tableView.deselectRowAtIndexPath(indexPath, animated: false)
}
loadSaved(1)を使用して、関数にロードする現在のページを指定して、データをフェッチします。この関数は、alomofireを使用してAPIリクエストを作成し、表示するデータをvar data:JSON!= []に設定します
だから私がやりたいことは、tableviewの一番下までスクロールするときですloadSaved(2)はもっと多くのデータをtableviewにロードするということです
UITableViewDelegateには table View(_:will Display:for Row At:)インスタンスメソッド があります。行。"
あなたの場合、私はそれを次のように使用します:
override open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == data.count-1 { //you might decide to load sooner than -1 I guess...
//load more into data here
}
}
コードによっては、すべてのデータをロードした場合に無限ループに陥らないようにするために、これについていくつかのチェックが必要になる場合があります...
いいえ、UITableView
には、無限スクロールまたはロードオンデマンドセルを実現する組み込み関数はありません。使用できるのは、UIScrollViewDelegate
にデフォルトで実装されているUITableView
の関数 scrollViewDidScroll(_:)
です。この方法で、ユーザーがUITableView
で定義された元の高さよりもスクロールするタイミングがわかります。
たとえば、次のコードのように:
var indexOfPageToRequest = 1
override func scrollViewDidScroll(scrollView: UIScrollView) {
// calculates where the user is in the y-axis
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height {
// increments the number of the page to request
indexOfPageToRequest += 1
// call your API for more data
loadSaved(indexOfPageToRequest)
// tell the table view to reload with the new data
self.tableView.reloadData()
}
}
UITableView
の最後に残りの要素を追加した結果を得るには、新しい要素をデータソースに追加する必要があります。この場合は、関数loadSaved(numberOfPage)
内のdata
です。
これがお役に立てば幸いです。
私はビクターの答えを修正し、それをとして使用しました
var indexOfPageRequest = 1
var loadingStatus = false
func loadData(){
if !loadingStatus{
loadingStatus = true
viewModel.getData(pageIndex: indexOfPageRequest)
}
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
// calculates where the user is in the y-axis
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height {
// increments the number of the page to request
indexOfPageRequest += 1
// call your API for more data
loadData()
// tell the table view to reload with the new data
self.tableView.reloadData()
}
}
データを受信したら、loadingStatusをtrueにリセットします。ビューがすでにより多くのデータをロードしているかどうかを確認せずに、tableviewがちらつきました。
上記の答えはすべて正しいですが、iOS 10以降では非常に良い
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath])
これは設定が必要なプリフェッチデリゲートです
tableView.prefetchDataSource = self
RayWeinderlich には、このトピックに関する素晴らしいチュートリアルがあります。 Raysは信頼できるサイトなので、ここにコードを投稿していません
ラビの答えは良さそうです。しかし、彼が最後に指摘したように、scrollViewDidScroll(_ scrollView: UIScrollView)
を使用する場合、tableView flickers
これは、tableViewをスクロールするたびにtableViewを再ロードしようとしているためです。
代わりに、scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
デリゲートメソッドを使用して、十分にスクロールし、tableViewのほぼ最後に到達したかどうかを判断できます。
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height {
indexOfPageRequest += 1
loadData()
self.tableView.reloadData()
}
}
上記も正しいですが、このコードも助けになるかもしれません。
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath){
if(indexPath.row == self.arryOfData.count-1){
if(self.pageNumber <= self.resPgNumber){
if(remaining != 0){
let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(44))
spinner.startAnimating()
tableView.tableFooterView = spinner
tableView.tableFooterView?.isHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.flgActivity = false
self.getActiveOrdersList()
}
}
else{
tableView.tableFooterView?.removeFromSuperview()
let view = UIView()
view.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(5))
tableView.tableFooterView = view
tableView.tableFooterView?.isHidden = true
}
}
else{
tableView.tableFooterView?.removeFromSuperview()
let view = UIView()
view.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(5))
tableView.tableFooterView = view
tableView.tableFooterView?.isHidden = true
}
}
else{
tableView.tableFooterView?.removeFromSuperview()
let view = UIView()
view.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(5))
tableView.tableFooterView = view
tableView.tableFooterView?.isHidden = true
}
}