【问题标题】:Auto scrolling to a cell with a specific value自动滚动到具有特定值的单元格
【发布时间】:2015-01-20 10:59:44
【问题描述】:

我在这样的表格视图中有一个数字列表。

如您所见,数字是重复的。让我们将一组重复数字视为一个。所以有一组1s,一组2s等等。

我想要做的是当应用程序启动时,我需要自动滚动到指定组的开始位置。在进一步解释之前,这是我到目前为止的代码。

import UIKit

class TableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {

    private var scrollToTime = true
    private var items = [Int]()
    private var groupNoToScroll = 12

    override func viewDidLoad() {
        super.viewDidLoad()

        items = [1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20, 21, 22, 22, 23, 23, 23]
    }

    // MARK: - UITableViewDataSource
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        cell.textLabel?.text = String(items[indexPath.row])

        return cell
    }

    // MARK: - UITableViewDelegate
    override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

        let lastRow = tableView.indexPathsForVisibleRows()?.last as NSIndexPath
        if indexPath.row == lastRow.row {
            if scrollToTime == true {
                let indexPath = NSIndexPath(forRow: groupNoToScroll, inSection: 0)
                tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
                scrollToTime = false
            }
        }
    }
}

我为变量groupNoToScroll 分配了值12。这意味着当应用程序启动时,我希望表格视图自动滚动到 12s 组的单元格的开头。

但目前我的代码所做的是滚动到第 12 个单元格,而不是具有 12 的单元格。我的问题是如何检查单元格的值并滚动到我指定?

【问题讨论】:

  • 你将不得不遍历你的数组并获得groupNoToScroll第一次出现的索引。
  • 然而,重写 tableView:willDisplayCell: 并不是一个好主意。你到底在做什么?
  • @HermannKlecker 我想在加载所有单元格后进行自动滚动。所以根据this 的回答,willDIsplayCell 是我需要检查的地方。有没有更好的方法来解决这个问题?
  • 否 willDisplayCell 不是为此而设计的。您将面临无限循环的风险。我只需使用 scrollToRowAtIndexPath 滚动到 viewDidLoad 中的相关单元格。工作正常。我做了很多。

标签: ios uitableview swift scroll autoscroll


【解决方案1】:

您可以使用查找项目的索引(将是它的行),然后滚动到该索引。
find 函数返回数组中特定元素的索引。

if let index = find(items, groupNoToScroll)
{
    let indexPath = NSIndexPath(forRow: index, inSection: 0)
    tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}

【讨论】:

  • 哇,这是一个简洁的功能。非常感谢。这是令人惊讶的简单和干净的语法。很酷。
  • 我不同意使用willDisplayCell 函数。我会在致电reloadData 后进行操作。 stackoverflow.com/questions/16071503/…
  • 如果 lastRow.row 是对应实际索引的那一行,可能是每组大小为 1 的情况,那么你会在这里陷入无限循环。 scrollToRowAtIndexPath 会导致 willDisplayCell 被调用。
  • @HermannKlecker 好的,我正在 viewDidAppear 方法中进行自动滚动,因为我希望每次离开此视图并返回时都会发生滚动。
  • @rakeshbs 在进行自动滚动之前是否需要每次调用reloadData()?如果有,能告诉我原因吗?
【解决方案2】:

斯威夫特 4:

let indexPath = IndexPath(row: row, section: section)
tableView.scrollToRow(at: indexPath, at: .top, animated: true)

(首先,当然,您必须根据要滚动到的单元格为行和部分分配值)

【讨论】:

    【解决方案3】:

    Swift 3.0

     let indexPath = NSIndexPath(forRow: 5, inSection: 0)
     tableView.scrollToRow(at: indexPath, at: .top, animated: true)
    

    Swift 4.0

    let lastRowIndex = self.tblRequestStatus!.numberOfRows(inSection: 0) - 1
    let pathToLastRow = IndexPath.init(row: lastRowIndex, section: 0)
    tableView.scrollToRow(at: pathToLastRow, at: .none, animated: false)
    

    【讨论】:

      【解决方案4】:

      执行此操作以查找数组中等于 groupNoToScroll 的第一个元素。然后,转到该行。

          var rowToGoTo:Int = 0 //Rather use the Swift find function.
          for x in items{
              if x == groupNoToScroll{
                  break
              }
              rowToGoTo++
          }
      
          let lastRow = tableView.indexPathsForVisibleRows()?.last as NSIndexPath
          if indexPath.row == lastRow.row {
              if scrollToTime == true {
                 let indexPath = NSIndexPath(row: rowToGoTo, section: 0)
                 tblBusList.scrollToRow(at: indexPath as IndexPath, at: .top, animated: true)
              }
          }
      

      但我建议在 viewDidAppear 中执行此操作。

      正如 Isuru 指出的,宁可使用 find 功能。

      【讨论】:

      • 感谢您的回答。虽然您的答案逻辑与@rakeshbs 的答案相同,但我接受了他的原因是因为使用了 Swift 函数find,我认为这是一种更优雅、更简洁的方法。但再次感谢:)
      • 这很有道理,我也会。我忘记了查找功能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多