IOS如何更新UITableViewCell
Posted
技术标签:
【中文标题】IOS如何更新UITableViewCell【英文标题】:IOS how to update UITableViewCell 【发布时间】:2012-10-29 11:46:00 【问题描述】:我制作了一个自定义 UITableViewCell:
SListViewCell * cell = nil;
// cell = [listView dequeueReusableCellWithIdentifier:CELL];
if (!cell)
cell = [[[SListViewCell alloc] initWithReuseIdentifier:CELL] autorelease];
listView.separatorColor = [UIColor clearColor];
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = index;
[btn setFrame:CGRectMake(0, 0, 42, 42)];
//setBtnImage will download image from network. when the UIButton click it is will change button image
[self setBtnImage:index btn:btn];
[btn addTarget:self action:@selector(typeTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn];
return cell;
typeTapped 方法:
-(void)typeTapped:(id)sender
UIButton* btn = (UIButton)sender;
//download image from network in ohter thread and change button' image.
NSThread * thread = [Thread alloc] initWith:@selecter(downloadImage:)....
[thread start];
[thread release];
//download image
-(void)downloadImage:(UIButton*)btn....
//download
UIImage* image= ....
//UITableView is not update
//it is will update when i scroll tableview.
[btn setImage:image ......];
那么我怎样才能在其他线程中更新 UITableViewCell。(如果我调用 reloadDate 它将会死机停止)(我可以滚动 tableview 来更新它)
【问题讨论】:
你试过[btn setNeedsDisplay];
吗?
【参考方案1】:
您可以在后台进行大部分处理,但任何更新 UI 的事情都必须在主线程上进行。
使用 Grand Central Dispatch (GCD) 可以轻松完成后台处理然后更新 UI。
- (void)typeTapped:(id)sender
UIButton* btn = (UIButton*)sender;
// Use Grand Central Dispatch to do the processing in the background.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
// Do download operation here... Something like:
NSData* imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://some_url.com/some.image"]];
UIImage* image = [UIImage imageWithData:imageData];
//Go back to the main thread to update the UI. this is very important!
dispatch_async(dispatch_get_main_queue(), ^
[btn setImage:image forState:UIControlStateNormal];
);
);
但是。在表格视图中有几个问题。
重复使用表格单元格。这意味着您的 UITableViewCell 中漂亮的 UIButton 可能不是您认为下载完成后的那个。它是同一个对象,但已重新配置为显示另一行的内容。
对于这些情况,最好的办法是使用 GCD 更新 NSArray 或其他数据结构,然后请求表格视图对单元格进行刷新。
// 在 UITableViewDelegate 中。
@implementation SomeViewController
NSMutableArray* _tableData;
// ...
// Someone tapped on the cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
// Do download operation here... Something like:
NSData* imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://some_url.com/some.image"]];
UIImage* image = [UIImage imageWithData:imageData];
if([_tableData count] < indexPath.row)
_tableData[indexPath.row] = image;
//Go back to the main thread to update the UI. this is very important!
dispatch_async(dispatch_get_main_queue(), ^
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
);
);
【讨论】:
【参考方案2】:任何 UI 更新只能发生在主线程上。我认为您不应该在另一个线程中更新 UITableViewCell。
来自苹果文档:
对应用程序用户界面的操作必须在 主线程。因此,您应该始终调用 UIView 的方法 应用程序主线程中运行的代码中的类。这 只有在创建视图时这可能不是绝对必要的 对象本身,但所有其他操作应发生在主 线程。
【讨论】:
那我该怎么做呢?我的 UIButton 在我点击它时会更改图像,需要从网络下载图像。 后台线程下载图片,主线程更新图片。以上是关于IOS如何更新UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章