viewWillDisappear,viewWillAppear不调用的解决方法

产生原因是用了UINavigationController. 
将UINavigationController的view作为subview添加到了其他viewController的view中。 
或者把UINavigationController添加到UITabbarController中了。 

此时,NavigationController的stack里面的viewController就收不到-(void)viewWillAppear:(BOOL)animated;等4个方法的调用。 

原因还不敢确定,应该是这样的结构破坏了消息的响应链。导航控制器上层的viewController只是接受了导航控制器的view,而不是controller. 估计tabbarController内部也是处理了set进去的controller的view。 

网上找了一些解决办法,但是有些只解决了Appear的方法调用,没有解决DisAppear的调用,最终找到了最好的一个解决办法,完美解决了Appear和DisAppear的调用。 

首先要实现一个UITabBarController的子类。并且实现UINavigationControllerDelegate 

- (void)viewDidLoad
{
    FirstViewController *firstViewController = [[FirstViewController alloc]init];
    SecondViewController *secondViewController = [[SecondViewController alloc]init];
    ThirdViewController *thirdViewController = [[ThirdViewController alloc]init];
    FourthViewController *fourthViewController = [[FourthViewController alloc]init];
    FifthViewController *fifthViewController = [[FifthViewController alloc]init];
    
    firstViewController.delegate = self;
    secondViewController.delegate = self;
    thirdViewController.delegate = self;
    fourthViewController.delegate = self;
    fifthViewController.delegate = self;
    
    NSArray *viewControllerArray = [NSArray arrayWithObjects:firstViewController,secondViewController,thirdViewController,fourthViewController,fifthViewController,nil]; 

    self.viewControllers = viewControllerArray;
    [self.view setFrame:CGRectMake(0, 0, 320, 460)];
    
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

以上FirstViewController到FifthViewController都是UINavigationController的子类。 

将delegate指向self。 

然后实现UINavigationControllerDelegate: 

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    //每次当navigation中的界面切换,设为空。本次赋值只在程序初始化时执行一次
    static UIViewController *lastController = nil;
    
    //若上个view不为空
    if (lastController != nil) 
    {
        //若该实例实现了viewWillDisappear方法,则调用
        if ([lastController respondsToSelector:@selector(viewWillDisappear:)]) 
        {
            [lastController viewWillDisappear:animated];
        }
    }
    
    //将当前要显示的view设置为lastController,在下次view切换调用本方法时,会执行viewWillDisappear
    lastController = viewController;
    
    [viewController viewWillAppear:animated];
}


这个方法是重点 
static UIViewController *lastController = nil;

静态变量只在程序初始化的时候执行一次,也就是赋值为nil。 
lastController指向的是新的界面要显示却还未显示的当前界面。 
举例子来说 ,如果navigation当前显示的是A,现在要push到B。因此在push B之前,lastController指向的是A  

//若上个view不为空
    if (lastController != nil) 
    {
        //若该实例实现了viewWillDisappear方法,则调用
        if ([lastController respondsToSelector:@selector(viewWillDisappear:)]) 
        {
            [lastController viewWillDisappear:animated];
        }
    }

像上边说的,lastController这时为A,因此不为nil,将执行A的viewWillDisappear。 

lastController = viewController;
    
 [viewController viewWillAppear:animated];


在执行了A的viewWillDisappear之后,将lastController设为B(当前viewController),然后调用B的viewWillAppear。 

本次方法执行结束了,如果navigation再push到C的时候,那么B的viewWillDisappear会执行,C的viewWillAppear会执行。这样就完美解决了viewWillAppear等4个 方法不调用 的问题。 

如果想实现viewDidAppear和viewDidDisAppear方法,则只需按照同样道理,实现UINavigationControllerDelegate 的 
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated; 
方法就行了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值