我正在通過iOS書,我一直在擴展一個示例程序的練習,當我偶然發現一個我不完全理解的問題。UINavigationController生命週期問題與 - viewWillAppear:沒有被調用
我目前正在使用具有rootView,detailView和第三級視圖的UINavigationController,我打算將其轉變爲模式視圖控制器。
一切都按預期工作。我的rootViewController是一個UITableView,它允許用戶選擇一行。該行會打開一個detailViewController給定對象顯示:
- 物品名稱
- 產品序列號
- 項目值
- 購買日期
在此DetailViewController有一個「更改購買日期「按鈕,顯示另一個ViewController以選擇新日期:
選擇日期和擊中「設置購買日期」按鈕後,我有viewWillDisappear方法將更改保存到項目目標的第三個視圖控制器,然後彈出一個視圖從堆棧返回到DetailViewController:
FILE :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已經在幕後更新了。這讓我相信,出於某種原因 - 這將不會再被調用。
如果我再次點擊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];
}
是的,謝謝。有時它只需要第二組眼睛。 – Matt 2013-04-08 20:51:04