[英]cellForRowAtIndexPath not called after reloadData in AppDelegate
我已经搜索了几个小时,尽管有很多类似的帖子,但找不到任何解决我的问题的方法。 我正在创建一个应用程序,该应用程序(从现在开始)正在使用startMonitoringSignificantLocationChanges
不断更新用户位置。 我有一个自定义的viewcontroller LocationsViewController
,它只是一个表视图,用于显示用户前往的每个位置。 在我的didUpdateLocations
:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
_currentLocation = _locationManager.location;
[_locations addObject:_currentLocation];
[_locationsViewController.tableView reloadData];
}
然后在LocationsViewController的numberOfRowsInSection
方法中,我有以下代码:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
AppDelegate * delegate = [AppDelegate sharedInstance];
NSLog(@"%lu", (unsigned long)[delegate.locations count]);
return [delegate.locations count];
}
现在,我在AppDelegate
实例化了LocationsViewController
,如下所示:
- (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;
}
在LocationsViewController
的numberOfRowsInSection
方法中,首次实例化LocationsViewController
时, delegate.locations
numberOfRowsInSection
的计数为0。 但是,在didUpdateLocations
之后,将使用1个位置填充数组delegate.locations
didUpdateLocations
。 然后,调用reloadData
方法,并再次调用numberOfRowsInSection
时,它返回1。如果该方法返回1,则应cellForRowAtIndexPath
其后调用cellForRowAtIndexPath
否则,将立即调用cellForRowAtIndexPath
。 但是由于某种原因,它没有被调用。 我想知道是否有人知道1.我的代码可能有什么问题(因为我使用情节提要,所以我认为它与任何格式或表格视图设置无关),我的dataSource
和delegate
都设置为self.tableView
,我还尝试实现heightForRowAtIndexPath
方法。 无论我做什么,我都没有运气。 调用reloadData
,将调用所有正确的方法,但cellForRowAtIndexPath
除外。 任何建议或导致错误之处的建议都会很棒。 如果有帮助,这里还有更多代码,谢谢:LocationsViewController.m
@implementation LocationsViewController
//*******************************************************************************************************************************
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
//*******************************************************************************************************************************
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be 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 to 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的评论是问题的核心。 在您的应用程序委托中,您要实例化LocationsViewController,然后再对其执行任何操作。 该视图控制器将永远不会出现在屏幕上,也永远不会做任何事情。
通常,让应用程序委托管理除初始设置和处理应用程序委托方法以外的任何事情都是很糟糕的。 您应该使视图控制器创建一个位置管理器对象,或者设置一个单独的位置服务对象来执行此操作。
直接进入视图控制器并直接操纵其视图对象也是一个非常糟糕的主意。 如果您需要一个视图控制器来更新其中一个视图,则应添加一个外部对象调用的方法,该方法将根据需要更改视图。
尽管有局限性,但使视图控制器管理位置管理器本身是最简单的解决方案。 仅当该视图控制器关心位置服务时,该方法才有效。
如果您的应用中还有其他关心位置信息的对象(视图控制器等),则应创建一个单独的对象来管理位置更新。 在这种情况下,您应该为它设置一个委托,或者给它一个位置更新块,以便在有可用更新时调用。 如果您希望同时通知应用程序中的多个视图控制器,则可能要使用通知管理器发出自定义位置更新通知。
您可能希望使位置服务对象成为单例对象。 这样,您的视图控制器就可以获取位置服务对象的单个实例,并将其设置为deleate /将它们的处理程序块设置为最前面的活动处理程序块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.