ios - cellForRowAtIndexPath not called after reloadData in AppDelegate -
i've been searching few hours , haven't found solutions problem despite abundance of similar posts. i'm creating app (at moment start) continuously updating users location using startmonitoringsignificantlocationchanges
. have custom viewcontroller locationsviewcontroller
tableview meant display each location user travels to. in didupdatelocations
:
- (void)locationmanager:(cllocationmanager *)manager didupdatelocations:(nsarray *)locations { _currentlocation = _locationmanager.location; [_locations addobject:_currentlocation]; [_locationsviewcontroller.tableview reloaddata]; }
and in numberofrowsinsection
method in locationsviewcontroller, have code:
- (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { appdelegate * delegate = [appdelegate sharedinstance]; nslog(@"%lu", (unsigned long)[delegate.locations count]); return [delegate.locations count]; }
now have locationsviewcontroller
instantiated in appdelegate
so:
- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { sharedinstance = self; _datahub = [[datahub alloc] init]; _locations = [[nsmutablearray alloc] init]; _locationmanager = [[cllocationmanager alloc] init]; _locationmanager.delegate = self; uistoryboard * storyboard = [uistoryboard storyboardwithname:@"main" bundle:nil]; _locationsviewcontroller = (locationsviewcontroller*) [storyboard instantiateviewcontrollerwithidentifier:@"locationsviewcontroller"]; _timepickviewcontroller = (timepickviewcontroller*) [storyboard instantiateviewcontrollerwithidentifier:@"timepickviewcontroller"]; if ([_locationmanager respondstoselector:@selector(requestwheninuseauthorization)]) { [_locationmanager requestalwaysauthorization]; } [_locationmanager startmonitoringsignificantlocationchanges]; return yes; }
in locationsviewcontroller
's numberofrowsinsection
method, count of delegate.locations
0 when locationsviewcontroller
first instantiated. after didupdatelocations
called, array delegate.locations
populated 1 location. reloaddata
method called , when numberofrowsinsection
called again returns 1. if method returns 1 cellforrowatindexpath
should called right after; reason, isn't getting called. wondering if knew, 1. problem code (i don't think has formatting or tableview setup since used storyboards), have datasource
, delegate
both set self.tableview
, tried implementing heightforrowatindexpath
method. , whatever do, have no luck. upon calling reloaddata
of correct methods called except cellforrowatindexpath
. suggestions or leads wrong great. here's more code if it'll help, thanks: locationsviewcontroller.m
@implementation locationsviewcontroller //******************************************************************************************************************************* - (void)viewdidload { [super viewdidload]; self.tableview.delegate = self; self.tableview.datasource = self; } //******************************************************************************************************************************* - (void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of resources can recreated. } //******************************************************************************************************************************* -(cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath { return 30.0f; } //******************************************************************************************************************************* #pragma mark - table view data source - (nsinteger)numberofsectionsintableview:(uitableview *)tableview { return 1; } //******************************************************************************************************************************* - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { appdelegate * delegate = [appdelegate sharedinstance]; nslog(@"%lu", (unsigned long)[delegate.locations count]); return [delegate.locations count]; } //******************************************************************************************************************************* - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { //cell setup appdelegate * delegate = [appdelegate sharedinstance]; static nsstring *cellidentifier = @"cell"; uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:cellidentifier]; if (cell == nil) { cell = [[uitableviewcell alloc] initwithstyle:uitableviewcellstylesubtitle reuseidentifier:cellidentifier]; } //edit cell clgeocoder *ceo = [[clgeocoder alloc]init]; cllocation * location = delegate.locations[indexpath.row]; [ceo reversegeocodelocation:location completionhandler:^(nsarray * placemarks, nserror *error) { clplacemark *placemark = [placemarks objectatindex:0]; //string hold address cell.textlabel.text = [nsstring stringwithformat:@"%f, %f", location.coordinate.latitude, location.coordinate.longitude]; cell.detailtextlabel.text = [nsstring stringwithformat:@"%@, %@", placemark.locality, placemark.administrativearea]; } ]; return cell; }
appdelegate.m
- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { sharedinstance = self; _datahub = [[datahub alloc] init]; _locations = [[nsmutablearray alloc] init]; _locationmanager = [[cllocationmanager alloc] init]; _locationmanager.delegate = self; uistoryboard * storyboard = [uistoryboard storyboardwithname:@"main" bundle:nil]; _locationsviewcontroller = (locationsviewcontroller*) [storyboard instantiateviewcontrollerwithidentifier:@"locationsviewcontroller"]; _timepickviewcontroller = (timepickviewcontroller*) [storyboard instantiateviewcontrollerwithidentifier:@"timepickviewcontroller"]; if ([_locationmanager respondstoselector:@selector(requestwheninuseauthorization)]) { [_locationmanager requestalwaysauthorization]; } [_locationmanager startmonitoringsignificantlocationchanges]; return yes; } //******************************************************************************************************************************* - (void)locationmanager:(cllocationmanager *)manager didupdatelocations:(nsarray *)locations { _currentlocation = _locationmanager.location; [_locations addobject:_currentlocation]; [_locationsviewcontroller.tableview reloaddata]; }
@rdelmar's comment core of problem. in app delegate you're instantiating locationsviewcontroller , never doing it. view controller never appear on screen, , never anything.
in general it's bad make app delegate manage other initial setup , handling app delegate methods. should either make view controller create location manager object or set separate location services object that.
it's very bad idea reach view controller , manipulate it's view objects directly. if need view controller update 1 of it's views should add method outside object calls, , method change view needed.
making view controller manage location manager far simplest solution, although it's got limitations. approach works if view controller cares location services.
if have other objects (view controllers, etc) in app care location information should create separate object managing location updates. in case should set delegate, or give location update block call when updates available. if want multiple view controllers in app notified @ same time might want use notification manager send out custom location update notifacations.
you might want make location services object singleton. way view controller(s) can fetch single instance of location services object , set deleate/set handler block active handler block when frontmost.
Comments
Post a Comment