滚动时如何在tableview中添加20 -20行的循环?

Posted

技术标签:

【中文标题】滚动时如何在tableview中添加20 -20行的循环?【英文标题】:How to make a loop appending 20 -20 rows in a tableview when scrolling? 【发布时间】:2019-06-21 08:16:02 【问题描述】:

我有一个表格视图,有时会得到 1000 或 40 甚至 4 个值,但我希望当我得到超过 100 个值时,我想以 10 到 10 的滚动显示我的数组。

向上滚动表格视图,我需要在向上滚动 10 行后暂停滚动,使用此代码会出错,我的数组在 [Any] 中,并且想要像 Facebook 和 instagram 一样滚动

我想先将我的数组分成 10 行,然后我可以追加接下来的 10 行。

    var allUserArray = [Any]()
    override func viewDidLoad() 
        super.viewDidLoad()

    var index = allUserArray.first 
    while index < limit 
    allUserArray.append(index)
    index = index + "1"
  

  

  extension AdvanceSearchViewController: UITableViewDataSource,           UITableViewDelegate 

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    return allUserArray.count 



   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "advanceSearch") as! AdvanceSearchTableViewCell


    let userData = allUserArray[indexPath.row] as! [String: Any]

    let dob = userData["dob"] as! String
    let age = self.getAgeFromDate(dob: dob)
    let photo1 = userData["photo1"] as? String
    let height = userData["Height"] as? String ?? "null"
    let religion = userData["Religion"] as? String ?? "null"


    cell.userNameLabel.text = "HM- \(userData["ProfileID"] as!   String)"
    cell.userProfessionLabel.text = userData["Profession"] as? String ?? "null"
    cell.userAgeLabel.text = "\(age), \(height), \(religion)"

    if let profileImage = photo1 
        urlStringOne = "\(USER_IMAGE_BASE_URL)\(profileImage)"
     else 
        if (UserDefaults.standard.value(forKey: "gender") as! String    == "Female") 
            urlStringOne = "\(USER_IMAGE_URL_MALE)"
         else 
            urlStringOne = "\(USER_IMAGE_URL_FEMALE)"
        
    

   loadImage(urlStringOne, cell)

    return cell



   func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    if self.allUserArray.count != nil 

        self.totalEnteries = self.allUserArray.count
        print("idealist/\(self.allUserArray.count)")
        print("total123/\(self.totalEnteries)")

        var entries = allUserArray.count - 1
          print("total-00/\(entries)")

      If indexPath.row == entries 
        print("(----------)")
        if allUserArray.count < totalEnteries 

            var index = allUserArray.count as! String
            self.limit = index + "20"
            while index < self.limit 
                self.allUserArray.append(index)
                index = index + "1"
                
            self.perform(#selector(self.loadTable), with: nil, afterDelay: 2.0)
          
        




   @objc func loadTable() 
    self.advanceSearchTableView.reloadData()
   


【问题讨论】:

【参考方案1】:

我会用一个例子来详细说明tableView中的pagination。你可以通过它,然后在你的项目中实现它。

1.假设您有一个包含大约 500 个元素的字符串数组。

var allUsers = [String](repeating: "User", count: 500)

2. 创建另一个 String array,它最初包含来自 allUsers array 的前 10 个元素。

var dataSource = [String]()

override func viewDidLoad() 
    super.viewDidLoad()
    self.addElements() //explained next..

dataSource array 将作为tableView 的实际dataSource

3.让我们维护一个offset,它会跟踪index,我们需要从中添加接下来的10个元素,即

var nextOffset = 0

func addElements() 
    let newOffset = nextOffset+10
    for i in nextOffset..<newOffset 
        dataSource.append(allUsers[i])
    
    nextOffset = newOffset

addElements() 方法只需添加从nextOffset 开始的接下来的 10 个元素。

4.UITableViewDataSource 方法看起来像,

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return dataSource.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = "\(dataSource[indexPath.row]) : \(indexPath.row)"
    return cell

5. 现在实现UITableViewDelegate 方法 - tableView(_:willDisplay:forRowAt:)

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    let currentCount = self.dataSource.count
    if currentCount < 500 && indexPath.row == (currentCount-1)  //last row
        self.addData()
        self.setUpLoaderView(toShow: true)
     else 
        self.setUpLoaderView(toShow: false)
    

在上述方法中,我检查了cell 是否正在为最后一个row 显示。如果是,那么我们使用addData() 方法向其添加更多数据,并使用setUpLoaderView(toShow:) 方法在底部显示loaderView

6.这是这两种方法的定义,

func addData() 
    DispatchQueue.main.asyncAfter(deadline: .now() + 10) 
        self.addElements()
        self.tableView.reloadData()
    


func setUpLoaderView(toShow: Bool) 
    if toShow 
        self.tableView.tableFooterView?.isHidden = false
        self.tableView.tableFooterView = self.loaderMoreView
     else 
        self.tableView.tableFooterView = UIView()
    

addData() 中,我根据您的要求添加了10 secondsdelay。因此,在使用新数据更新 tableView 之前,10 seconds 将可以看到 loader

7. loaderMoreView 只是一个设置为tableFooterViewUIActivityIndicatorView,例如:

private lazy var loaderMoreView: UIView = 
    let loaderView = UIActivityIndicatorView(style: .whiteLarge)
    loaderView.color = UIColor.gray
    loaderView.startAnimating()
    return loaderView
()

【讨论】:

您好,请详细说明 500 项数组,如何调用整个 500 项数组,或者我可以调用前缀 10 项数组,然后添加数组接下来 10 项。 问题已解决,但使用后端分页,以节省加载 tableview 的时间。 你能帮帮我吗,如何在表格视图底部调用默认的 UIRefreshcontrol 其即将到来的下拉请求,我想从底部加载我的行数据......我想要刷新表格视图底部的微调器【参考方案2】:

创建一个标志变量来检查表格现在在哪个单元格上 // var showMore : Bool = false 我建议将您的数组转换为更友好的类型,例如 String

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

if allUserArray.count > 100 && showMore != true 
    return 20
else if allUserArray.count > 100 && showMore == true 
    return allUserArray.count 
else 
    return 20




func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
     if indexpath.row == 20 
    // append new content if any
    // update flag : showMore = true
    // reload table

【讨论】:

嗨,我已经以行数实现了这段代码,但是如何追加剩下的数组。 ? func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int print("Number_Results/(allUserArray.count)") if allUserArray.count > 50 return allUserArray.prefix(10).count else return allUserArray .count 在 swift 中,您可以使用 array.append() 甚至是 oldArray += NewArray 来追加数组【参考方案3】:

我建议您使用 Bond 框架来绑定您的数据。它建立在 RxSwift 之上。因此,在您的情况下,您只需要一个 Mutable Observable Array 并将该数组与您的 tableView 绑定。 let userArray = MutableObservableArray(allUserArray)

userArray.bind(to: collectionView, cellType: UserCell.self)  (cell, name) in
cell.titleLabel.text = name

从“willDisplay”调用一个函数并更改数组中的值。使用这种方法,您只需要维护一个数组,它就会自动显示在您的 tableView 中。

https://github.com/DeclarativeHub/Bond

【讨论】:

以上是关于滚动时如何在tableview中添加20 -20行的循环?的主要内容,如果未能解决你的问题,请参考以下文章

添加新数据时,Tableview 会滚动到顶部。无限滚动

插入新行时 TableView 滚动到中间

如何为每次用户滚动时更新的每个 tableview 单元格添加一个计时器?

当我滚动 tableview 时,如何让 headerView 滚动(不停留在 tableview 的顶部)伴随 UItableViewCell

如何在 UIViewController 的 tableView 顶部添加自定义视图并能够一起滚动

滚动时 Tableview 单元格中标签的自动收缩功能不起作用