`

viewWillDisappear,viewWillAppear不调用的解决方法

    博客分类:
  • iOS
 
阅读更多
产生原因是用了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;
方法就行了



2
2
分享到:
评论

相关推荐

    构建 View 时可能用到的代理函数调用顺序 viewdidload

    本文将重点介绍`viewDidLoad`与`viewWillAppear`两个关键方法的调用时机及作用,并通过图表形式总结常见的生命周期方法调用顺序,以便于开发者更好地理解和应用。 #### 视图控制器的生命周期 视图控制器是iOS应用...

    UIViewController生命周期详解

    在初始化过程中,需要注意的是,子类通常会先调用父类的初始化方法,然后再执行自己的初始化逻辑。例如: ```swift override init() { super.init() // 子类的初始化逻辑 } ``` #### 二、视图加载阶段 初始化...

    TabBarController与NavigationController嵌套的例子

    TabBarController与... ⁃ viewWillAppear(), viewDidAppear(), viewWillDisappear(), 
viewDidDisappear()等方法不被调用的解决方法(解释在这里) Coding Style: Daniel's Objective-C Coding Style Guidelines

    UIView的生命周期

    6. `viewWillDisappear`方法在视图即将被隐藏前调用,比如被另一个视图覆盖或以其他方式隐藏。在这个方法中,开发者可以执行一些清理工作,比如取消一些不需要再执行的动画效果。 7. `viewDidDisappear`方法在视图...

    iOS利用Runtime实现友盟页面数据统计的功能示例

    在viewWillAppear方法中,我们需要调用beginLogPageView方法来开始统计页面的访问次数。在viewWillDisappear方法中,我们需要调用endLogPageView方法来结束统计页面的访问次数。 下面是一个示例代码: ```objc - ...

    iOS中的View Controller Lifecycle

    在iOS开发中,View Controller(视图控制器)生命周期是开发者必须深入理解的重要概念。...在开发过程中,一定要根据需要在适当的生命周期方法中添加代码,避免在不合适的时机执行操作,以保证应用的稳定性和性能。

    iOS App开发中UIViewController类的使用教程

    通常情况下,你不应重写此方法,而应使用`viewDidLoad`。 4. `viewDidLoad`:视图加载完成后调用,是初始化视图和设置视图属性的最佳时机。在这里,你可以添加子视图、配置控件等。 5. `viewWillAppear:`:视图...

    Viewrrlkalkadsva

    3. **视图出现**: 在View即将出现在屏幕上之前,`viewWillAppear:`方法会被调用;当View完全出现在屏幕上后,`viewDidAppear:`方法会被调用。 4. **视图消失**: 当View即将从屏幕上消失时,`viewWillDisappear:`...

    IOS 生命周期

    当你创建一个新的空项目并运行时,你可以观察到如`viewDidLoad`、`viewWillAppear:`、`viewDidAppear:`、`viewWillDisappear:`和`viewDidDisappear:`等生命周期方法的调用顺序。这些方法会在特定的时刻被系统自动...

    iOS系统中导航栏的转场解决方案与最佳实践.docx

    在push过程中,UINavigationController会调用一系列方法,包括pushViewController:animated:、viewWillAppear:、viewWillDisappear:等。需要注意的是,UINavigationController通常是UINavigationBar的代理,其代理...

    ios电话面试题库

    其中,viewDidLoad 在视图加载后被调用,viewWillAppear 在视图即将可见时调用,viewDidAppear 在视图已完全过渡到屏幕上时调用,viewWillDisappear 在视图被驳回时调用,viewDidDisappear 在视图被驳回后调用。...

    视图控制器无动画版代码完整版.7z

    - 视图布局:`viewWillAppear:`, `viewWillDisappear:`在视图即将出现或消失时调用,用于更新界面。 - 视图显示:`viewDidAppear:`, `viewDidDisappear:`在视图完全可见或不可见时调用。 - 销毁:在视图控制器...

    IOS屏幕旋转.zip

    可能还包含了适当的视图控制器生命周期方法的重写,如viewWillAppear:和viewWillDisappear:,以便在切换过程中正确地更新UI和管理状态。 为了实现平滑的过渡效果,开发者可能使用了动画来隐藏和显示视图控制器,使...

    iOS开发技巧之状态栏字体颜色的设置方法

    在本文中,我们详细介绍了iOS开发技巧之状态栏字体颜色的设置方法,包括在info.plist中设置、在个别VC中设置、使用preferredStatusBarStyle方法设置、解决状态栏字体颜色不一致的问题等。开发者可以根据实际情况选择...

    视图控制对象的区别及使用

    4. `viewWillAppear:` 和 `viewWillDisappear:` 这两个方法分别在视图即将显示和即将消失时调用,常用于更新视图的状态。 5. `viewDidAppear:` 和 `viewDidDisappear:` 视图完全显示和完全消失后调用,可用于执行...

    IOS应用源码之视图控制器(无动画版) .rar

    5. viewWillAppear和viewWillDisappear:这两个方法在视图的显示和隐藏过程中也会被调用,可用于动态改变视图状态。 三、导航控制器与pushViewController 在iOS应用中,视图控制器常常需要通过导航控制器...

    UIViewController

    - `viewWillAppear:`:视图即将显示时调用,适合做视图显示前的准备工作。 - `viewDidAppear:`:视图已经显示出来时调用,视图完全可见后执行。 - `viewWillDisappear:`:视图即将消失时调用,通常在此进行清理...

    iOS NSTimer循环引用的几种解决办法

    我们可以在 viewWillAppear 中开启 NSTimer,在 viewWillDisappear 中关闭它,这样可以避免循环引用问题。同时,我们也可以在团队编程规范中规定 Controller 退出时必须销毁 NSTimer,避免内存泄露。 NSTimer 循环...

    swift-系统返回按钮事件拦截Swift版本

    在`viewWillAppear(_:)`方法中添加观察者,在`viewWillDisappear(_:)`方法中移除观察者。这样,任何页面都可以响应返回事件,而无需在每个页面中重复代码。 ```swift override func viewWillAppear(_ animated: ...

    05-UI控件1

    3. viewWillAppear在视图即将显示时调用,可以用于调整视图状态,可能会被多次调用(如导航栈切换)。 4. viewDidAppear表示视图已经完全显示,适合在此进行进一步的界面交互初始化。 5. viewWillDisappear在视图...

Global site tag (gtag.js) - Google Analytics