ios 如何遍历 UITableView 的单元格?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6914183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:55:59  来源:igfitidea点击:

How can I loop through UITableView's cells?

iosuitableview

提问by Paul Warkentin

I have n sections (known amount) and X rows in each section (unknown amount. Each row has a UITextField. When the user taps the "Done" button I want to iterate through each cell and do some conditional tests with the UITextField. If the tests pass data from each cell is written to a database. If not, then a UIAlert is shown. What is the best way to loop through the rows and if there is a more elegant solution to this please do advise.

我在每个部分有 n 个部分(已知数量)和 X 行(未知数量。每行都有一个 UITextField。当用户点击“完成”按钮时,我想遍历每个单元格并使用 UITextField 进行一些条件测试。如果测试将每个单元格的数据写入数据库。如果没有,则显示 UIAlert。循环遍历行的最佳方法是什么,如果有更优雅的解决方案,请提出建议。

回答by Paul Warkentin

If you only want to iterate through the visible cells, then use

如果您只想遍历可见单元格,请使用

NSArray *cells = [tableView visibleCells];

If you want all cells of the table view, then use this:

如果你想要表格视图的所有单元格,那么使用这个:

NSMutableArray *cells = [[NSMutableArray alloc] init];
for (NSInteger j = 0; j < [tableView numberOfSections]; ++j)
{
    for (NSInteger i = 0; i < [tableView numberOfRowsInSection:j]; ++i)
    {
        [cells addObject:[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]]];
    }
}

Now you can iterate through all cells:
(CustomTableViewCellis a class, which contains the property textFieldof the type UITextField)

现在,你可以通过所有细胞循环:
CustomTableViewCell是一类,它包含的属性文本字段类型的UITextField

for (CustomTableViewCell *cell in cells)
{
    UITextField *textField = [cell textField];
    NSLog(@"%@"; [textField text]);
}

回答by andrewCanProgram

Here is a nice swift implementation that works for me.

这是一个很好的快速实现,对我有用。

 func animateCells() {
        for cell in tableView.visibleCells() as! [UITableViewCell] {
            //do someting with the cell here.

        }
    }

回答by 2ank3th

Accepted answer in swift for people who do not know ObjC (like me).

对于不了解 ObjC 的人(如我),迅速接受了答案。

for section in 0 ..< sectionCount {
    let rowCount = tableView.numberOfRowsInSection(section)
    var list = [TableViewCell]()

    for row in 0 ..< rowCount {
        let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: row, inSection: section)) as! YourCell
        list.append(cell)
    }
}

回答by luhuiya

for xcode 9 use this - (similar to @2ank3th but the code is changed for swift 4):

对于 xcode 9,使用这个 - (类似于@2ank3th,但代码已更改为 swift 4):

let totalSection = tableView.numberOfSections
for section in 0..<totalSection
{
    print("section \(section)")
    let totalRows = tableView.numberOfRows(inSection: section)

    for row in 0..<totalRows
    {
        print("row \(row)")
        let cell = tableView.cellForRow(at: IndexPath(row: row, section: section))
        if let label = cell?.viewWithTag(2) as? UILabel
        {
            label.text = "Section = \(section), Row = \(row)"
        }
    }
}

回答by Darshit Shah

for (UIView *view in TableView.subviews) {
    for (tableviewCell *cell in view.subviews) {
       //do
    }
}

回答by JOM

Since iOS may recycle tableView cellswhich are off-screen, you have to handle tableView one cell at a time:

由于iOS 可能会回收屏幕外的tableView 单元格,因此您必须一次处理一个单元格:

NSIndexPath *indexPath;
CustomTableViewCell *cell;

NSInteger sectionCount = [tableView numberOfSections];
for (NSInteger section = 0; section < sectionCount; section++) {
    NSInteger rowCount = [tableView numberOfRowsInSection:section];
    for (NSInteger row = 0; row < rowCount; row++) {
        indexPath = [NSIndexPath indexPathForRow:row inSection:section];
        cell = [tableView cellForRowAtIndexPath:indexPath];
        NSLog(@"Section %@ row %@: %@", @(section), @(row), cell.textField.text);
    }
}

You can collect an NSArray of all cells beforehands ONLY, when the whole list is visible. In such case, use [tableView visibleCells]to be safe.

您可以仅在整个列表可见时预先收集所有单元格的 NSArray。在这种情况下,使用[tableView visibleCells]是安全的。

回答by budidino

quick and dirty:

又快又脏:

for (UIView *view in self.tableView.subviews){
    for (id subview in view.subviews){
        if ([subview isKindOfClass:[UITableViewCell class]]){
            UITableViewCell *cell = subview;
            // do something with your cell
        }
    }
}

回答by whyoz

Here's a completely different way of thinking about looping through UITableView rows...here's an example of changing the text that might populate your UITextView by looping through your array, essentially meaning your tableView cell data.

这是一种完全不同的思考 UITableView 行循环的方式……这是一个通过循环遍历数组来更改可能填充 UITextView 的文本的示例,本质上是指 tableView 单元格数据。

All cells are populated with data from some kind of model. A very common model would be using an NSObject and NSMutableArray of those objects. If you were in didSelectRowAtIndexPath, you would then want to do something like this to affect the row you're selecting after modifying the array above:

所有单元格都填充有来自某种模型的数据。一个非常常见的模型是使用这些对象的 NSObject 和 NSMutableArray。如果你在 didSelectRowAtIndexPath 中,那么你会想要做这样的事情来影响你在修改上面的数组后选择的行:

for(YourObject *cellRow in yourArray)
{
    if(![cellRow.someString isEqualToString:@""])
    {
         cellRow.someString = @"";
    }
    //...tons of options for conditions related to your data
}

YourObject *obj = [yourArray objectAtIndex:indexPath.row];
obj.someString = @"selected";
[yourArray insertObject:views atIndex:indexPath.row];
[yourArray removeObjectAtIndex:indexPath.row];
[yourTable reloadData];

This code would remove all the UITextField's text in every row except the one you selected, leaving the text "selected" in the tapped cell's UITextField as long as you're using obj.someString to populate the field's text in cellForRowAtIndexPath or willDisplayRowAtIndexPath using YourObjectand yourArray.

此代码将删除除您选择的行之外的每一行中的所有 UITextField 文本,只要您使用 obj.someString 填充 cellForRowAtIndexPath 中的字段文本,或 willDisplayRowAtIndexPath 使用YourObject你的数组

This type of "looping" doesn't require any conditions of visible cells vs non visible cells. If you have multiple sections populated by an array of dictionaries, you could use the same logic by using a condition on a key value. Maybe you want to toggle a cells imageView, you could change the string representing the image name. Tons of options to loop through the data in your tableView without using any delegated UITableView properties.

这种类型的“循环”不需要可见单元格与不可见单元格的任何条件。如果您有多个由字典数组填充的部分,您可以通过对键值使用条件来使用相同的逻辑。也许您想切换单元格 imageView,您可以更改表示图像名称的字符串。在不使用任何委托的 UITableView 属性的情况下循环遍历 tableView 中的数据的大量选项。