是否可以刷新UITableView中的单个UITableViewCell?


182

我有一个UITableView使用UITableViewCells 的自定义。每个UITableViewCell按钮都有2个按钮。单击这些按钮将更改UIImageView单元格中的图像。

是否可以分别刷新每个单元以显示新图像?任何帮助表示赞赏。

Answers:


323

有了单元格的indexPath后,您可以执行以下操作:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

在Xcode 4.6和更高版本中:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

当然,您可以设置任何喜欢的动画效果。


4
在这里挑剔,但当然,如果您只刷新单个单元格,则可能要使用它[NSArray arrayWithObject:]
Leo Cassarani 2011年

57
同样,在这种情况下,beginUpdatesendUpdates是不必要的。
2011年

2
OP没有设置任何动画,因此无需调用begin / endupdates
kubi

2
只要该方法在最新的公共Xcode版本中不被弃用,则所有iOS版本都可以。
亚历杭德罗·伊万

1
@Supertecnoboff是正确的,但在某些时候它可能会被替换或改变其行为。最好尽快处理折旧
AlejandroIván15年

34

我只是尝试打电话给-[UITableView cellForRowAtIndexPath:],但是那没用。但是,以下示例对我有用。我allocreleaseNSArray用于紧密内存管理。

- (void)reloadRow0Section0 {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
    [indexPaths release];
}

这里需要[indexPaths版本]吗?我以为您只需要自己分配对象即可。
powerj1984

4
他确实分配了indexPaths数组。但是更好的问题是,为什么他认为“紧密的内存管理”是必要的。自动发行将在这里很好地完成这项工作。
John Cromartie 2013年

22

迅速:

func updateCell(path:Int){
    let indexPath = NSIndexPath(forRow: path, inSection: 1)

    tableView.beginUpdates()
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
    tableView.endUpdates()
}

在哪里调用此方法?
主代理X

18

reloadRowsAtIndexPaths:很好,但是仍然会迫使UITableViewDelegate方法触发。

我能想到的最简单的方法是:

UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath];

这是重要的调用你configureCell:的主线程中执行,如在非UI线程它不会工作(同样的故事reloadData/ reloadRowsAtIndexPaths:)。有时添加以下内容可能会有所帮助:

dispatch_async(dispatch_get_main_queue(), ^
{
    [self configureCell:cell forIndexPath:indexPath];
});

还有必要避免在当前可见视图之外进行的工作:

BOOL cellIsVisible = [[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] != NSNotFound;
if (cellIsVisible)
{
    ....
}

您为什么不希望呼叫代表?
kernix

这是最好的方法,因为与reloadRowsAtIndexPaths:或reloadData方法相反,它不会强制表格视图一直滚动到顶部。
ZviBar

我这样做了,最终被电池回收的事实所困扰
Traveling Man'3

16

如果使用自定义TableViewCells,则通用

[self.tableView reloadData];    

除非您退出当前视图并返回,否则无法有效回答该问题。第一个答案都没有。

要成功地重新加载第一个表格视图单元而无需切换视图,请使用以下代码:

//For iOS 5 and later
- (void)reloadTopCell {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}

插入以下刷新方法,该方法调用上述方法,以便您可以自定义仅重新加载顶部单元格(如果需要,也可以重新加载整个表格视图):

- (void)refresh:(UIRefreshControl *)refreshControl {
    //call to the method which will perform the function
    [self reloadTopCell];

    //finish refreshing 
    [refreshControl endRefreshing];
}

现在,您已经进行了排序,在内部viewDidLoad添加了以下内容:

//refresh table view
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];

[self.tableView addSubview:refreshControl];

现在,您具有自定义刷新表功能,该功能将重新加载顶部单元格。要重新加载整个表格,请添加

[self.tableView reloadData]; 您的新刷新方法。

如果您希望每次切换视图时都重新加载数据,请实现以下方法:

//ensure that it reloads the table view data when switching to this view
- (void) viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
}

6

迅捷3:

tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()

4

只需使用iOS 6中的新文字语法来稍微更新这些答案-您可以对单个对象使用Paths = @ [indexPath],对于多个对象可以使用Paths = @ [indexPath1,indexPath2 ......]。

就个人而言,我发现数组和字典的文字语法非常有用且节省大量时间。一方面,它更容易阅读。而且,它消除了在任何多对象列表的末尾都不需要nil的需要,而后者始终是个人的bugaboo。我们都有风车倾斜,是吗?;-)

只是以为我会把这个混在一起。希望能帮助到你。


格雷格说,请问那里实际上是该语法的示例吗?谢谢!
Fattie 2013年

3

这是Swift 5的UITableView扩展:

import UIKit

extension UITableView
{    
    func updateRow(row: Int, section: Int = 0)
    {
        let indexPath = IndexPath(row: row, section: section)

        self.beginUpdates()
        self.reloadRows(at: [indexPath as IndexPath], with: UITableView.RowAnimation.automatic)
        self.endUpdates()
    }

}

致电

self.tableView.updateRow(row: 1)

0

我需要升级单元,但是我想关闭键盘。如果我用

let indexPath = NSIndexPath(forRow: path, inSection: 1)
tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
tableView.endUpdates()

键盘消失

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.