从UITableViewCell刷新UITableView

时间:2009-06-25 01:49:03

标签: iphone cocoa-touch uitableview

是否有一种简单的方法可以从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

7 个答案:

答案 0 :(得分:18)

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

- (void)reloadImage:(NSNotification *)notification
{
    UIImage *image = [[SSImageManager sharedImageManager] getImage:[[notification userInfo] objectForKey:@"imageUrl"];
    [self setImage:image];
    [self setNeedsLayout];
}

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

self.imageView.image = newImage;

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

答案 4 :(得分:0)

CodeGrue是对的。经过几天思考为什么[subclassOjb.tableView reloadData]无法正常工作后,我放弃了尝试理解并解决了我认识的两种方法并且很容易实现:1-通知中心(来自tableviewcell你不应该使用)这个)2或使用superview获取tableview属性的句柄(这对于uitableviewcells来说是完美的。)

请注意,使用superview方法只适用于你的uitableviewcell类,如果你有一个自定义单元格,你可能会有一个uitableviewcell类,superview是你的tableviewcontroller或者你拥有的uitableview委托+数据源。

现在,如果你需要从另一个类重新加载你的tableview,那么数据源类可以说是单例或其他类;你应该在tableview类中使用一个块来将数据加载到另一个线程上,使用内部块来重新加载mainthread上的表。

//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];
    });
});

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

无论如何,对于tableviewcell,只需在你的动作中使用以下内容来重新加载数据(信用到CodeGrue)

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

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

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

答案 5 :(得分:0)

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

声明

你应该总是使用委托模式,以下是在未来版本中可能再次破解的黑客攻击。

Hack从单元格重新加载数据

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

[parentTable reloadData];

答案 6 :(得分:-1)

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