Iphone 从UITableViewCell刷新UITableView

Iphone 从UITableViewCell刷新UITableView,iphone,cocoa-touch,uitableview,Iphone,Cocoa Touch,Uitableview,是否有一种简单的方法可以从UITableView单元格内触发[UITableView重载数据]?我正在加载初始表格显示后要显示的远程图像,并且使用self.image=newImage更新图像不会刷新表格。重置单元格的文本值确实会刷新表格,但这似乎有些草率 MyTableViewCell.h @interface MyTableViewCell : UITableViewCell {} - (void)imageWasLoaded:(ImageData *) newImage; MyTable

是否有一种简单的方法可以从UITableView单元格内触发[UITableView重载数据]?我正在加载初始表格显示后要显示的远程图像,并且使用
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

试试[yourtableview重新加载数据];
将图像设置为新图像后,仅重新加载需要重新加载的节/行的成本较低。在iphonesdk3.0中,有一些方法可以做到这一点。

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

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


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

我做了您正试图做的事情。你要找的是
needsLayout
。也就是说(这是我的UITableViewCell子类上的通知观察者):


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

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


CodeGrue是对的。在思考了几天为什么[subassojb.tableView reloadData]不起作用之后,我放弃了试图理解这一点,选择了我所知道的唯一两种方法:1-通知中心(从tableviewcell中,您不应该使用这个)2-或者使用superview来获得tableView属性的句柄(这非常适合uitableviewcells)

请注意,使用superview方法仅适用于uitableviewcell类,如果您有一个自定义单元格,则可能会有一个uitableviewcell类,其中superview是您的tableviewcontroller,或者是uitableview委托+数据源的任何其他类

现在,如果您需要从另一个类、数据源类(比如singleton)或其他类重新加载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];
    });
});
如果您在不同的视图上,并且发生了需要在表视图上重新加载表的情况。此时,表不在屏幕上,如果没有人会看到它,您没有理由重新加载表。只需添加[self.tableview reloadDAta]当用户返回到tableviewcontroller视图时,它将动态地重新加载表

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

**不同的话题,但对于你们这些现在就开始的人来说。这将使你们免于可能的头痛- 在创建tableclass之后,甚至在开始处理其委托方法之前,请执行以下操作:在viewDidLoad中添加以下代码:

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

如果有人想从单元格中重新加载表,但发现CodeGrue的答案不起作用,您仍然可以这样做,但需要再次检查

免责声明 为此,您应该始终使用委托模式,接下来的攻击可能会在将来的版本中再次出现

黑客从手机中重新加载数据
setNeedsLayout是2.0+:这正是我想要的。谢谢!如果你有很多数据,那将非常昂贵。最好只更新加载图像的单元格。@SergiusGee你需要遍历superview层次结构。我相信在父UITableView和子UIView之间有一个私有的
UIView
ableViewCell。不要这样做。你不能只是从堆栈下面假设东西。
UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];
//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];
    });
});
UITableView *parentTable = (UITableView *)self.superview;
[parentTable reloadData];
self.tableView.delegate = self;
self.tableView.dataSource = self; 
UITableView *parentTable = (UITableView *)self.superview;
if (![parentTable isKindOfClass:[UITableView class]]) {
    parentTable = (UITableView *) parentTable.superview;
}

[parentTable reloadData];