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