从 UITableViewCell 刷新 UITableView

Posted

技术标签:

【中文标题】从 UITableViewCell 刷新 UITableView【英文标题】:Refreshing the UITableView from UITableViewCell 【发布时间】:2009-06-25 01:49:03 【问题描述】:

有没有一种简单的方法可以从 UITableViewCell 中触发 [UITableView reloadData]?我正在加载要在初始表格显示后显示的远程图像,并且使用self.image = newImage 更新图像不会刷新表格。重置单元格的文本值确实会刷新表格,但这似乎很草率。

MyTableViewCell.h

@interface MyTableViewCell : UITableViewCell 
- (void)imageWasLoaded:(ImageData *) newImage;

MyTableViewCell.m

@implementation MyTableViewCell
- (void)imageWasLoaded:(UIImage *) newImageData 
    self.image = newImage; //does not refresh table

    //would like to call [self.tableView reloadData] here,
    //but self.tableView does not exist.

    //instead I use the below line
    self.text = self.text; //does refresh table

@end

【问题讨论】:

【参考方案1】:

我做了你想做的事。你要找的东西是needsLayout。也就是说(这是我的 UITableViewCell 子类上的通知观察者):

- (void)reloadImage:(NSNotification *)notification

    UIImage *image = [[SSImageManager sharedImageManager] getImage:[[notification userInfo] objectForKey:@"imageUrl"];
    [self setImage:image];
    [self setNeedsLayout];

这将在您的图像中弹出,而无需重新加载整个表格,这会变得非常昂贵。

【讨论】:

这正是我想要的。谢谢!【参考方案2】:

使用superview 属性获取对包含UITableView 的引用。然后告诉它“reloadData”:

UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];

【讨论】:

@SergiusGee 您需要遍历超级视图层次结构。我相信在父 UITableView 和子 UITableViewCell 之间有一个私有的UIView 不要那样做。你不能只假设堆栈下的东西。【参考方案3】:

仅重新加载需要重新加载的部分/行的成本更低。在 iPhone SDK 3.0 中,有一些方法可以做到这一点。

【讨论】:

setNeedsLayout 是 2.0+:tuvix.apple.com/iphone/library/documentation/GraphicsImaging/…【参考方案4】:

嗯。那么imageWasLoaded:是一些异步图片加载代码调用的委托方法吗?实际上,设置self.image 不会更新图像似乎很奇怪。您是否尝试将自己的UIImageView 添加到单元格而不是使用图像属性?可能是一种 hack,但这样图像应该会立即更新(无需重新加载整个表格视图,这绝对是不可取的)。

更好的是:如果您使用的是 SDK 3.0,则可以使用 UITableViewCell 中的新 imageView 属性(不过我没有尝试过):

self.imageView.image = newImage;

实际上,几周前我也需要做同样的事情。但是,我的方法是继承 UIImageView 并在该类中执行所有异步图像加载/更新。我这样做的主要原因是我想要一个通用且可重用的组件,它可以在不同的表格视图单元格(或其他地方)中使用。

【讨论】:

【参考方案5】:

CodeGrue 是对的。经过几天思考为什么 [subclassOjb.tableView reloadData] 不起作用后,我放弃了试图理解这一点,并选择了我知道有效且很容易实现的唯一两种方法:1-通知中心(来自 tableviewcell 你不应该使用这个)2-或使用超级视图来处理您的 tableview 属性(这非常适合 uitableviewcells)。

请注意,使用 superview 方法仅适用于您的 uitableviewcell 类,如果您有一个自定义单元格,您可能会有一个 uitableviewcell 类,其超级视图是您的 tableviewcontroller 或任何您拥有的带有 uitableview 委托 + 数据源的类。

现在,如果您需要从另一个类(数据源类)重新加载您的 tableview,让我们说一个单例或其他类;您应该在 tableview 类中使用一个块在不同的线程上加载数据,并使用内部块在主线程上重新加载表。

//handle tablview to show spinner (you have to lower your tableview out of the way yourself if you are calling this method)
[self.tableView setContentOffset:CGPointMake(0, -rf.frame.size.height) animated:YES];

//start spinner animation here
[rf beginRefreshing];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                         (unsigned long)NULL), ^(void) 
    // Load Data from data source class here
    [myDataSourceClass fetchDataMethod];

    dispatch_async(dispatch_get_main_queue(), ^

         //Reload data and stop spinner
        [self.tableView reloadData];
        [rf endRefreshing];

        //handle tablview to hide spinner atrributed title
        [self.tableView setContentOffset:CGPointMake(0, 0) animated:YES];
    );
);

如果您在不同的视图上并且发生了一些事情,您需要在您的表视图上重新加载您的表。好吧,那时你的桌子不在屏幕上,如果没有人看到它,你没有理由重新加载你的桌子。当用户返回到您的 tableviewcontroller 视图时,只需将 [self.tableview reloadDAta] 添加到您的 viewWillAppear 方法中,它就会即时重新加载表格。

无论如何,对于 tableviewcell,只需在您的操作中使用以下内容来重新加载数据(归功于 CodeGrue)

UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];

**不同的主题,但对于那些现在开始的人。这将使您免于头痛 - 在创建你的表类之后,甚至在你开始处理它的委托方法之前 - 这样做:在你的 viewDidLoad 添加以下代码:

self.tableView.delegate = self;
self.tableView.dataSource = self; 

【讨论】:

【参考方案6】:

任何正在寻找从单元格中重新加载表格的方法并发现 CodeGrue 的答案不起作用的人,您仍然可以这样做,但您需要仔细检查。

免责声明

您应该始终为此使用委托模式,以下是可能在未来版本中再次破坏的 hack。

破解以重新加载单元格中的数据

UITableView *parentTable = (UITableView *)self.superview;
if (![parentTable isKindOfClass:[UITableView class]]) 
    parentTable = (UITableView *) parentTable.superview;


[parentTable reloadData];

【讨论】:

【参考方案7】:

尝试 [yourtableview reloadData]; 将图像设置为新图像后

【讨论】:

如果您有大量数据,那将非常昂贵。最好只更新加载图像的单元格。

以上是关于从 UITableViewCell 刷新 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

UITableviewcell的性能问题

UITableviewcell 是错误的数据

获取图像后从其 imageView 刷新 UITableViewCell 布局

UITableViewCell 中 UIImageView 上的 UITapGestureRecognizer

UITableViewCell:允许选择性删除

自定义 UITableViewCell 的高度