uitableview - iOS- Update UITableViewCell information without reloading the row? -
let's have uitableview displays list of file metadata, , want show download_progress of each file in uilabel of custom uitableviewcell. (this arbitrarily long list - dynamic cells reused).
if want update label without calling either reloaddata or reloadrowsatindexpaths, how can it?
for wondering - don't want call either of reload... methods because there's no need reload entire cell each percentage point update on download_progress.
the solutions i've come across are:
adding cell key-value observer
file'sdownload_progress.calling
cellforrowatindexpath...directly obtain label , change it's text.
however, kvo in general isn't fun api work - , less when add cell reuse mix. calling cellforrowatindexpath directly each time percentage point added feels dirty though.
so, possible solutions? appreciated.
thanks.
as corollary doug's response, here ended going with:
each file has unique identifier, made responsible posting notifications updates attributes (think kvo, without hassle):
i made filenotificationtype enum (i.e. filenotificationtypedownloadtriggered, , filenotificationtypedownloadprogress). send progress nsnotification's userinfo nsdictionary along filenotificationtype.
- (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]; }); } the file object has method enumerate types of notifications send:
- (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; } so when update attribute of file elsewhere, this:
nsdictionary *attributes = @{@"download_progress" : @(<progress_integer>)}; [file_instance postnotificationwithtype:filenotificationtypedownloadprogress andattributes:attributes]; on receiving end, table view delegate implemented these methods add / remove custom uitableviewcells observers these notifications:
- (void)tableview:(uitableview *)tableview willdisplaycell:(uitableviewcell *)cell forrowatindexpath:(nsindexpath *)indexpath { file *file = [modelobject getfileatindex:indexpath.row]; (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]; } finally, custom uitableviewcell has implement receivefilenotification: method:
- (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: { // progress break; } case filenotificationtypedownloadstatus: { // status break; } case fsepisodenotificationtypedownloadtriggered: { // if download triggered break; } default: break; } } hopefully helps looking update tableview cells without having reload them! benefit on key-value observing won't issues if file object deallocated cell still observing. don't have call cellforrow....
enjoy!
Comments
Post a Comment