32

假设我有一个 UITableView 有多行。我想在某个时间点将所有 UITableViewCells 作为 NSArray 获取。我努力了

[tableView visibleCells] 

但这种方法存在一个问题:我不能拥有当前不在当前屏幕中的所有单元格。所以我转向了另一种方法:

-(NSArray *)cellsForTableView:(UITableView *)tableView
{
    NSInteger sections = tableView.numberOfSections;
    NSMutableArray *cells = [[NSMutableArray alloc]  init];
    for (int section = 0; section < sections; section++) {
        NSInteger rows =  [tableView numberOfRowsInSection:section];
        for (int row = 0; row < rows; row++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];   // **here, for those cells not in current screen, cell is nil**
            [cells addObject:cell];
        }
    }
    return cells;
}

但似乎这种方法仍然无法获取那些未显示在屏幕中的单元格。谁可以帮我这个事?

4

9 回答 9

22

我认为这是不可能的,仅仅是因为 tableView 不存储所有单元格。它使用一种缓存机制,该机制仅存储一些不可见的单元格以供重用。

为什么需要所有细胞?也许你可以实现,你正在尝试做的事情,否则。

于 2012-10-23T10:28:35.510 回答
15

这是 Swift 3.0 中最简单的解决方案

func getAllCells() -> [UITableViewCell] {

    var cells = [UITableViewCell]()
    // assuming tableView is your self.tableView defined somewhere
    for i in 0...tableView.numberOfSections-1
    {
        for j in 0...tableView.numberOfRowsInSection(i)-1
        {
            if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: j, inSection: i)) {

               cells.append(cell)
            }

        }
    }
 return cells
 }
于 2015-09-21T06:32:47.603 回答
7

每次创建单元格时,您都可以将其添加到 NSMutableArray 中,您可以在需要时对其进行解析:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *Cell = [self dequeueReusableCellWithIdentifier:@"Custom_Cell_Id"];
    if (Cell == NULL)
    {
        Cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Custom_Cell_Id"]];
        [Cells_Array addObject:Cell];
    }
}

- (void) DoSomething
{
    for (int i = 0;i < [Cells count];i++)
    {
        CustomCell *Cell = [Cells objectAtIndex:i];
        //Access cell components
    }
}
于 2014-01-31T09:54:48.000 回答
2

但是,获取当前单元格的更简单的实现是使用 Set 即 O(1)

/// Reference to all cells.
private var allCells = Set<UITableViewCell>()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Your_Cell_ID") as! UITableViewCell
    if !allCells.contains(cell) { allCells.insert(cell) }
    return cell
}
于 2017-03-21T03:02:13.500 回答
2

我想我找到了解决这个问题的窍门。尝试这个 ;)

self.tableView.frame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.contentSize.width, self.tableView.contentSize.height);

UITableViewcellForRowAtIndexPath根据高度调用,tableView.frame因此您应该更新 tableView 的高度。

于 2018-07-18T16:21:34.313 回答
1

我想你可能会误解如何UITableView是如何实现的。要理解的重要一点是,不可见的细胞实际上并不存在(或者至少它们可能不存在)

随着UITableView滚动,旧单元格被新单元格替换 dequeueReusableCellWithIdentifier

-(UITableViewCell) cellForRowAtIndexPath (NSIndexPath *)indexPath
于 2012-10-23T10:29:00.857 回答
1

功能解决方案 swift 5.0

extension UITableView {
    /**
     * Returns all cells in a table
     * ## Examples:
     * tableView.cells // array of cells in a tableview
     */
    public var cells: [UITableViewCell] {
      (0..<self.numberOfSections).indices.map { (sectionIndex: Int) -> [UITableViewCell] in
          (0..<self.numberOfRows(inSection: sectionIndex)).indices.compactMap { (rowIndex: Int) -> UITableViewCell? in
              self.cellForRow(at: IndexPath(row: rowIndex, section: sectionIndex))
          }
      }.flatMap { $0 }
    }
}
于 2018-05-22T11:42:34.717 回答
0

你想要那些文本字段的值吗?如果是,您可以通过带有 indexpath.row 的文本字段的标签属性访问

于 2012-10-23T10:38:31.470 回答
0

SWIFT 5 UITableView 确实重用了单元格,这意味着您可以将 100 个项目加载到 UITableView 中,但是您一次只能显示 10 个项目。如果用户想要显示其他项目,他需要滚动。因此,对于内存优化,UITableView 仅加载 13 个单元(显示 10 个单元 + 预加载 3 个单元)。如果要获取所有可见单元格(在我们的示例中为 10 个单元格),您可以使用:

let visibleCells = yourTableView.visiblecells

但是,如果您想获取所有已加载的单元格(在我们的示例中为 13 个单元格),我建议使用以下扩展名:

extension UITableView {

func getAllCells() -> [UITableViewCell] {
    var cells = [UITableViewCell]()
    for i in 0..<self.numberOfSections
    {
        for j in 0..<self.numberOfRows(inSection: i)
        {
            if let cell = self.cellForRow(at: IndexPath(row: j, section: i)) {
                cells.append(cell)
            }
            
        }
    }
    return cells
}

}

然后,您可以通过调用以下方式获取所有单元格:

let allLoadedCells = yourtableView.getAllCells()
于 2021-10-11T16:03:49.890 回答