iOS- 在不重新加载行的情况下更新 UITableViewCell 信息?
iOS- Update UITableViewCell information without reloading the row?
假设您有一个显示 file
元数据列表的 UITableView
,并且您想要显示 UILabel
中每个文件的 download_progress
自定义 UITableViewCell
。 (这是一个任意长的列表 - 因此动态单元格将被重用)。
如果你想在不调用 reloadData
或 reloadRowsAtIndexPaths
的情况下更新标签,你该怎么做?
对于那些想知道的人 - 我不想调用任何一个 reload...
方法,因为不需要为 download_progress
上的每个百分比更新重新加载整个单元格。
我遇到的唯一解决方案是:
将单元格添加为 file
的 download_progress
的键值观察器。
直接调用cellForRowAtIndexPath...
获取标签并更改其文本。
然而,
KVO 通常不是一个有趣的工作 api - 当你将单元重用添加到混合中时更是如此。每次加一个百分点就直接调用cellForRowAtIndexPath
感觉有点脏
那么,有哪些可能的解决方案?任何帮助将不胜感激。
谢谢。
我会创建一个自定义单元格,我猜你已经完成了。然后我会让单元格监听您的下载进度方法 post 的特定通知,然后在那里更新标签。您必须想出一种方法来指定某个单元格的下载进度,可能是通过标题字符串或可以告诉您的下载进度方法的唯一内容,因此您的单元格更新方法可以确保注释是意味着它。如果您需要我澄清我对此的思考过程,请告诉我。
作为 Doug 回应的必然结果,这是我最终的结果:
每个 file
都有一个唯一的标识符,所以我让它负责发布关于其属性更新的通知(想想 KVO,但没有麻烦):
我制作了一个 FileNotificationType
枚举(即 FileNotificationTypeDownloadTriggered
和 FileNotificationTypeDownloadProgress
)。然后我会将进度与 FileNotificationType
.
一起发送到 NSNotification
的 userInfo NSDictionary
- (void)postNotificationWithType:(FileNotificationType)type andAttributes:(NSDictionary *)attributes
{
NSString *unique_notification_id = <FILE UNIQUE ID>;
NSMutableDictionary *mutable_attributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
[mutable_attributes setObject:@(type) forKey:@"type"];
NSDictionary *user_info = [NSDictionary dictionaryWithDictionary:mutable_attributes];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:unique_notification_id object:nil userInfo:user_info];
});
}
file
对象还有一个方法来枚举它可以发送的通知类型:
- (NSArray *)notificationIdentifiers
{
NSString *progress_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>;
NSString *status_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>
NSString *triggered_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>
NSArray *identifiers = @[progress_id, status_id, triggered_id];
return identifiers;
}
因此,当您在其他地方更新 file
的属性时,只需执行以下操作:
NSDictionary *attributes = @{@"download_progress" : @(<PROGRESS_INTEGER>)};
[file_instance postNotificationWithType:FileNotificationTypeDownloadProgress andAttributes:attributes];
在接收端,我的 table 视图委托实现了这些方法来添加/删除我的自定义 UITableViewCells
作为这些通知的观察者:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
File *file = [modelObject getFileAtIndex:indexPath.row];
for (NSString *notification_id in file.notificationIdentifiers)
{
[[NSNotificationCenter defaultCenter] addObserver:cell selector:@selector(receiveFileNotification:) name:notification_id object:nil];
}
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[[NSNotificationCenter defaultCenter] removeObserver:cell];
}
最后,自定义 UITableViewCell
必须实现 receiveFileNotification:
方法:
- (void)receiveFileNotification:(NSNotification *)notification
{
FileNotificationType type = (FileNotificationType)[notification.userInfo[@"type"] integerValue];
// Access updated property info with: [notification.userInfo valueForKey:@"<Your key here>"]
switch (type)
{
case FileNotificationTypeDownloadProgress:
{
// Do something with the progress
break;
}
case FileNotificationTypeDownloadStatus:
{
// Do something with the status
break;
}
case FSEpisodeNotificationTypeDownloadTriggered:
{
// Do something if the download is triggered
break;
}
default:
break;
}
}
希望这对希望更新 tableView 单元而无需重新加载它们的人有所帮助!键值观察的好处是,如果 File
对象在单元格仍在观察的情况下被释放,您将不会遇到问题。我也不必打电话给 cellForRow...
.
尽情享受吧!
假设您有一个显示 file
元数据列表的 UITableView
,并且您想要显示 UILabel
中每个文件的 download_progress
自定义 UITableViewCell
。 (这是一个任意长的列表 - 因此动态单元格将被重用)。
如果你想在不调用 reloadData
或 reloadRowsAtIndexPaths
的情况下更新标签,你该怎么做?
对于那些想知道的人 - 我不想调用任何一个 reload...
方法,因为不需要为 download_progress
上的每个百分比更新重新加载整个单元格。
我遇到的唯一解决方案是:
将单元格添加为
file
的download_progress
的键值观察器。直接调用
cellForRowAtIndexPath...
获取标签并更改其文本。
然而,
KVO 通常不是一个有趣的工作 api - 当你将单元重用添加到混合中时更是如此。每次加一个百分点就直接调用cellForRowAtIndexPath
感觉有点脏
那么,有哪些可能的解决方案?任何帮助将不胜感激。
谢谢。
我会创建一个自定义单元格,我猜你已经完成了。然后我会让单元格监听您的下载进度方法 post 的特定通知,然后在那里更新标签。您必须想出一种方法来指定某个单元格的下载进度,可能是通过标题字符串或可以告诉您的下载进度方法的唯一内容,因此您的单元格更新方法可以确保注释是意味着它。如果您需要我澄清我对此的思考过程,请告诉我。
作为 Doug 回应的必然结果,这是我最终的结果:
每个 file
都有一个唯一的标识符,所以我让它负责发布关于其属性更新的通知(想想 KVO,但没有麻烦):
我制作了一个 FileNotificationType
枚举(即 FileNotificationTypeDownloadTriggered
和 FileNotificationTypeDownloadProgress
)。然后我会将进度与 FileNotificationType
.
NSNotification
的 userInfo NSDictionary
- (void)postNotificationWithType:(FileNotificationType)type andAttributes:(NSDictionary *)attributes
{
NSString *unique_notification_id = <FILE UNIQUE ID>;
NSMutableDictionary *mutable_attributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
[mutable_attributes setObject:@(type) forKey:@"type"];
NSDictionary *user_info = [NSDictionary dictionaryWithDictionary:mutable_attributes];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:unique_notification_id object:nil userInfo:user_info];
});
}
file
对象还有一个方法来枚举它可以发送的通知类型:
- (NSArray *)notificationIdentifiers
{
NSString *progress_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>;
NSString *status_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>
NSString *triggered_id = <FILE UNIQUE ID + FILENOTIFICATIONTYPE>
NSArray *identifiers = @[progress_id, status_id, triggered_id];
return identifiers;
}
因此,当您在其他地方更新 file
的属性时,只需执行以下操作:
NSDictionary *attributes = @{@"download_progress" : @(<PROGRESS_INTEGER>)};
[file_instance postNotificationWithType:FileNotificationTypeDownloadProgress andAttributes:attributes];
在接收端,我的 table 视图委托实现了这些方法来添加/删除我的自定义 UITableViewCells
作为这些通知的观察者:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
File *file = [modelObject getFileAtIndex:indexPath.row];
for (NSString *notification_id in file.notificationIdentifiers)
{
[[NSNotificationCenter defaultCenter] addObserver:cell selector:@selector(receiveFileNotification:) name:notification_id object:nil];
}
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[[NSNotificationCenter defaultCenter] removeObserver:cell];
}
最后,自定义 UITableViewCell
必须实现 receiveFileNotification:
方法:
- (void)receiveFileNotification:(NSNotification *)notification
{
FileNotificationType type = (FileNotificationType)[notification.userInfo[@"type"] integerValue];
// Access updated property info with: [notification.userInfo valueForKey:@"<Your key here>"]
switch (type)
{
case FileNotificationTypeDownloadProgress:
{
// Do something with the progress
break;
}
case FileNotificationTypeDownloadStatus:
{
// Do something with the status
break;
}
case FSEpisodeNotificationTypeDownloadTriggered:
{
// Do something if the download is triggered
break;
}
default:
break;
}
}
希望这对希望更新 tableView 单元而无需重新加载它们的人有所帮助!键值观察的好处是,如果 File
对象在单元格仍在观察的情况下被释放,您将不会遇到问题。我也不必打电话给 cellForRow...
.
尽情享受吧!