一文弄懂ios 视图进入/离开窗口的监听方法:willMoveT

2024-02-24  本文已影响0人  Wesson

导语

需求开发中经常要监听某个页面的可见与不可见,例如某个自定义View在可见时要播放动画,当不可见时(例如被其他页面暂时遮挡,或者退出该视图)要暂停动画。常用的监听方法是-[UIView willMoveToWindow:],本文讲介绍该方法的调用时机以及分享作者遇到过的一个隐蔽的坑。

方法简述

- (void)willMoveToWindow:(nullable UIWindow *)newWindow;

newWindow: The window object that will be at the root of the receiver's new view hierarchy. This parameter may be nil.
如果视图将要从可见变为不可见,即:被从主窗口上移除掉,则newWindow为nil
相反,如果视图将要从不可见变为可见,即:即将添加到主窗口上,则newWindow为当前程序的keyWindow

调用时机

从上面的方法简述来看,当view的视图层级的根窗口改变时,就会触发该方法回调。为了更深刻地理解这个方法,我们还需要知道它在view和viewController的整个生命周期中的位置
为了获取整个生命周期,写如下代码来获取日志

// VC的代码
- (void)viewDidLoad{
    NSLog(@"vc[ceshi]viewDidLoad");
    MyView *myView = [[MyView alloc] init];
    MySubView *mySubView = [[MySubView alloc] init];
    [self.view addSubview:myView];
    [myView addSubview:mySubView];
}

获取到的日志如下:


image.png view和VC的生命周期.png

如上图,展示了view和viewController生命周期中的主要节点。根据日志的打印顺序,图中的箭头表示时间的先后顺序,不一定能够代表调用/触发关系。

遇到的一个坑

需求开发时,发现在当前页面切换到另一个VC时,willMoveToWindow出现了这样的调用情况
willMoveToWindow:nil
willMoveToWindow:newWindow
willMoveToWindow:nil
视图第一次被从窗口上移除,这是预期内的
然而后面视图又被添加回窗口,然后再次移除,这是预期外的表现。
断点查看第二次调用,即willMoveToWindow:newWindow时的堆栈


image.png

如上图,可以看到底层调用有许多和UINavigationController、aniamtion相关的方法,推测和我们切换VC时的动画有关。
下面是我们切换VC的代码

UINavigationController *navVC = UIApplication.sharedApplication.keyWindow.rootViewController;
[navVC pushViewController:vc animated:**YES**];

我们尝试将YES改为NO,不要切换VC时的过渡动画,果然额外的两次willMoveToWindow的调用没有了。这印证了我们的推测:当pushViewController设置animated为YES 的时候,

结论:psuhViewController:animated的过渡动画,会导致willMoveToWindow被额外调用两次

上一篇 下一篇

猜你喜欢

热点阅读