UINavigationController生命周期问题 - viewWillAppear:没有被调用

时间:2013-04-08 13:14:04

标签: ios uinavigationcontroller viewwillappear

我正在阅读一本iOS书籍,当我偶然发现一个我完全不理解的问题时,我一直在扩展一个示例程序。

我目前正在使用一个UINavigationController,它有一个rootView,一个detailView和一个第三级视图,我打算将其变成一个模态视图控制器。

一切都按预期工作。我的rootViewController是一个UITableView,允许用户选择一行。该行将打开给定对象的detailViewController,显示:

  1. 项目标题
  2. 项目序列号
  3. 项目值
  4. 购买日期
  5. 在这个DetailViewController上有一个“更改购买日期”按钮,它显示另一个ViewController来选择一个新日期:
    enter image description here enter image description here

    选择日期并点击“设置购买日期”按钮后,我有viewWillDisappear方法将更改保存到第三个ViewController中的Item对象,然后从堆栈弹出一个视图返回到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对象已在幕后更新。这让我相信由于某种原因-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];
    
    
    }
    

1 个答案:

答案 0 :(得分:0)

会给你一个问题:

- (void) viewDidDisappear:(BOOL)animated {

[super viewWillDisappear:animated];

应该是

- (void) viewWillDisappear:(BOOL)animated {

[super viewWillDisappear:animated];

错字?或者这样做能解决问题吗?