我正在阅读一本 iOS 书籍,当我偶然发现一个我不完全理解的问题时,我一直在扩展一个示例程序以供练习。
我目前正在使用具有 rootView、detailView 和第三级视图的 UINavigationController,我打算将其变成模式视图控制器。
一切都按预期工作。我的 rootViewController 是一个 UITableView,它允许用户选择一行。该行将为显示的给定对象打开一个 detailViewController:
- 项目标题
- 项目序列号
- 项目价值
- 购买日期
在这个 DetailViewController 上有一个“更改购买日期”按钮,它显示另一个 ViewController 以选择新日期:
选择一个日期并点击“设置购买日期”按钮后,我让 viewWillDisappear 方法将更改保存到第三个 ViewController 中的项目对象,然后从堆栈中弹出一个视图以返回到 DetailViewController:
文件:PurchaseDateViewController.m:
- (void) viewDidDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Clear first responder
[[self view] endEditing:YES];
// "Save" the changes made to the creationDate
[_item setDateCreated:[purchaseDatePicker date]];
/* Debugging Log */
// Create a NSDateFormatter that will turn the date into a simple string
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
// NSLogging
NSLog(@"Original Date: %@", [dateFormatter stringFromDate:_itemsOldDate]);
NSLog(@"DatePicker Date: %@", [dateFormatter stringFromDate:[purchaseDatePicker date]]);
NSLog(@"Stored Date: %@", [dateFormatter stringFromDate:[_item dateCreated]]);
// Reload the DetailViewController to update the changes if the NavigationController is used to return to the DetailViewController
}
#pragma mark Action Methods to Update the Data Source
- (IBAction)setPurchaseDate:(id)sender {
// "Save" the changes made to the creationDate
[_item setDateCreated:[purchaseDatePicker date]];
// Move back 1 level on the NavigationController Stack
[[self navigationController] popViewControllerAnimated:YES];
}
- (void)cancelChange {
// "Reset" the changes made to the creationDate
[_item setDateCreated:_itemsOldDate];
// Move back 1 level on the NavigationController Stack
[[self navigationController] popViewControllerAnimated:YES];
}
上面列出的所有方法都有效。
当使用“设置购买日期”按钮并且从堆栈中弹出 PurchaseDateViewController 时,DetailViewController 会立即更新。
但是,当我按下 NavigationController 后退按钮时,视图不会更新,并且旧日期仍然存在于 DetailViewController 上。真正奇怪的是,正如我的 NSLog 语句所证明的那样,Item Object 已经在幕后进行了更新。这让我相信由于某种原因 -viewWillAppear 不再被调用。
如果我再次点击 NavigationController 的后退按钮并重新选择同一行,则可以确认这一点。当我采用这种测试方法时,当从 rootViewController 重新进入 DetailViewController 时,日期会更新为新日期。由于 DetailViewController 已从 NavigationController 堆栈中删除,然后再次实例化(因此再次调用 DetailViewController 的 viewWillAppear),因此进行了更改。
为什么在这种情况下不调用 viewWillLoad 方法?使用 UINavigationControls 时为什么不存在更改,有没有办法显式重新加载视图?克服这个问题的推荐方法是什么?
在写这篇文章时,我确实找到了一种强制调用 viewWillAppear 方法的方法,但我觉得必须有一种更“标准化”的方法来克服这个问题。最佳做法是什么?
这是我用来解决问题的“作弊”:
PurchaseDateViewController.m
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[viewController viewWillAppear:animated];
}
- (void) viewDidDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Clear first responder
[[self view] endEditing:YES];
// "Save" the changes made to the creationDate
[_item setDateCreated:[purchaseDatePicker date]];
/* Debugging Log */
// Create a NSDateFormatter that will turn the date into a simple string
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
// NSLogging
NSLog(@"Original Date: %@", [dateFormatter stringFromDate:_itemsOldDate]);
NSLog(@"DatePicker Date: %@", [dateFormatter stringFromDate:[purchaseDatePicker date]]);
NSLog(@"Stored Date: %@", [dateFormatter stringFromDate:[_item dateCreated]]);
// Reload the DetailViewController to update the changes if the NavigationController is used to return to the DetailViewController
[self navigationController:[self navigationController] willShowViewController:_detailViewController animated:YES];
}