我想刷新一个已经完成异步加载的单元格。
我知道有两种方法可以做到,但没有一种方法是我想要的。这就是我所知道的:
[myTableView reloadData];
或者
[myTableView beginUpdates];
[myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPathOfMyCell] withRowAnimation:UITableViewRowAnimationNone];
[myTableView endUpdates];
直接从我的自定义UITableViewCell
调用我的asynchrone方法来加载图像。这意味着它独立于我的UITableView
。我的最终解决方案是将my UITableViewCell
作为参数传递给当前单元格的索引。这看起来像是一个非常丑陋的解决方案。
有人知道另一种解决方案吗?
修改
[myCacheClass loadUIImageFromPath:photo.mediumDistURL];
loadUIImageFromPath:(NSString *) path{
//Some code to load the image.
if(![weakSelf.delegate respondsToSelector:@selector(MyCacheDidLoadImageFromCache:)])
[weakSelf setDelegate:appDelegate.callbacksCollector];
[weakSelf.delegate MyCacheDidLoadImageFromCache:image];
}
MyCacheDidLoadImageFromCache
的实施:
- (void) CacheCacheDidLoadImageFromCache: (UIImage *) image{
DDLogInfo(@"Successfully load image from cache : %@", [image description]);
myImageView.image = image;
}
答案 0 :(得分:1)
已经为这种情况定义了许多更好的解决方案。您可以使用复杂的第三方代码AsyncImageView,AFNetworking。
答案 1 :(得分:1)
您可以通过NSNotificationCenter进行间接。该表可以订阅通知:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(dataAvailableNotification:)
name:@"MyDataNowAvailable"
object:nil];
当数据可用时,缓存将发布:
[[NSNotificationCenter defaultCenter] postNotificationName:@"MyDataNowAvailable"
object:self userInfo:@{@"Data": theData}];
然后该表通过将数据映射到适当的单元格并触发重绘来响应此通知:
- (void) dataAvailableNotification:(NSNotification *) notification
{
DataObject *theData = notification.userInfo[@"Data"];
// add code here to find which cell(s) this data is displayed in
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
// etc
}
这种方法的好处是它可以推广到多个视图中显示相同数据的情况。
答案 2 :(得分:0)
您不需要传递UITableViewCell
,而是通过NSIndexPath
来获取该特定单元格。 &安培;然后使用reloadRowsAtIndexPaths
方法重新加载。
要获取chache类文件中的表容器,请使用属性。
@property (nonatomic, assign) UITableView *tableView;
然后在实施中
loadUIImageFromPath:(NSString *) path forCell(NsIndexPath*)indexPath{
//Some code to load the image.
if(![weakSelf.delegate respondsToSelector:@selector(MyCacheDidLoadImageFromCache:)])
[weakSelf setDelegate:appDelegate.callbacksCollector];
[weakSelf.delegate MyCacheDidLoadImageFromCache:image forCell:indexPath];
}
- (void) CacheCacheDidLoadImageFromCache: (UIImage *) image forCell(NSIndexPath*)indexPath{
DDLogInfo(@"Successfully load image from cache : %@", [image description]);
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
myImageView.image = image;
//tableView is from property & you have to pass NSIndexPath
}
&安培;在您的ViewController中将此属性指定为
myCacheClass.tableView = yourTableView;
[myCacheClass loadUIImageFromPath:photo.mediumDistURL forCell:indexPath];
答案 3 :(得分:0)
在设置子类TableViewCell之后将其放在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
中。
NSURL *imageURL = [NSURL URLWithString:@"your image url"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
if (imageData) {
UIImage *image = [UIImage imageWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
YourCellSubclass *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell) {
updateCell.yourImageView.image = image;
}
});
}
}
});
在此代码中,每个单元格在加载单元格时都会发出异步图像请求。如果数据返回,它会尝试从中创建UIImage。如果该图像有效,则仅在单元格仍然可见时才更新主线程上的图像。
每次加载单元格时,此代码都会对图像进行网络调用。您可能希望最有可能实现某种缓存。您要执行的缓存类型/数量取决于您的数据的动态程度。
答案 4 :(得分:0)
所以这是基于块的解决方案,无需将tableView
和indexPath
指针传递给单元格。我们将实现completionBlock
。您应该熟悉这种方法:
<强> CustomCell.h:强>
// Define block as a typedef
typedef void (^CellCompletionHandler)(BOOL);
@interface MyTableViewCell : UITableViewCell
// Take a predefined block as a parameter
- (void)initWithImageURL:(NSURL *)URL completionHanlder:(CellCompletionHandler)completion;
@end
<强> CustomCell.m:强>
- (void)initWithImageURL:(NSURL *)URL completionHanlder:(CellCompletionHandler)completion
{
// Take the URL and call cell's inner loading method
// Pass the completion block to it
[self doSomethingWithCellCompletionHandler:completion];
}
- (void)doSomethingWithCellCompletionHandler:(CellCompletionHandler)completion
{
// When you finish loading your image from cache
// call this to tell the block that you finished
completion(YES);
}
<强>的cellForRowAtIndexPath:强>
[cell initWithImageURL:[NSURL URLWithString:@"your URL"]completionHanlder:^(BOOL finishedLoading) {
if(finishedLoading)
{
// Here you can use indexPath to check whether it's visible
// in order to reload it
NSLog(@"Finished loading image");
}
}];