willMoveToWindow被调用两次

问题描述:

我在调用willMoveToWindow:,我遇到了一个问题,它在视图上被调用了两次。willMoveToWindow被调用两次

当一个新的视图控制器被推到UINavigationController

willMoveToWindow:被称为与nil值现有的视图(有道理的,因为该视图屏幕外移动)

在该时间之后,该方法willMoveToWindow:被再次调用,但现在与原来的窗口。

我最初的想法是,交叉混合和调用window财产之前的原始方法已经拉开。

要对我创建了一个小样本项目,并确认相同的行为在安全方面。

基本上我需要一种方法来确保视图不在window(因为当视图移动到实际上不应该运行的窗口时(至少不是两次),我触发逻辑)

作为参考的问题可以用下面的代码被复制:

@implementation RandomView 

    -(void)willMoveToWindow:(UIWindow *)newWindow { 
    // when the new view controller is pushed - 
    //the method is called twice on the existing view (on the screen view)- 
    //first time will be called with nil - 
    //second time with the original window 
     NSLog(@"********%s <RandomView %p> <Window %p>",__PRETTY_FUNCTION__,self,newWindow); 
    } 

    -(void)didMoveToWindow { 
     NSLog(@"********%s <RandomView %p> <Window %p>",__PRETTY_FUNCTION__,self,self.window); 
    } 
    @end 

    @implementation ViewController 

    - (void)viewDidLoad { 
     [super viewDidLoad]; 
     RandomView *k = [[RandomView alloc] initWithFrame:self.view.bounds]; 
     [self.view addSubview:k]; 
    } 


    -(void)viewDidAppear:(BOOL)animated { 
     [super viewDidAppear:animated]; 
     static dispatch_once_t onceToken; 
     dispatch_once(&onceToken, ^{ 
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
       ViewController *vc = [[ViewController alloc] init]; 
       [self.navigationController pushViewController:vc animated:YES]; 
      }); 
     }); 

     //[self becomeFirstResponder]; 
    } 
    @end 

EDIT 控制台

[RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0> 
    [RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0> 
    //THIS IS THE ISSUE 
    [RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x0> 
    [RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x0> 
    [RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0> 
    [RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0> 

    [RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x0> 
    [RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x0> 
+1

你不能检查'view.window'吗?你为什么需要改头换面?搅拌不好。 – Andy

+0

那不相关 - 这只是一个附注。 问题是它被称为两次 - –

+0

它对我来说很有意义。 1. ViewDidLoad添加子视图2.视图添加到窗口。通过该命令链,您必须获得两次willMoveToWindow调用。您可能需要使用某个标志或某物来注册相关事件。 – Andy

我也面临着同样的问题

但通过响应者链查找视图层次结构后,有一个小的不同的可以检查。我不确定这是否安全。

但我认为Apple以错误的顺序做了动画代码,如果他们先将动画视图添加到窗口中,则willMoveToWindow:将不会调用两次。

2017-03-08 22:49:35.167 view[36189:410065] show 
0x7fa9c36059f0,MyView 
0x7fa9c3407cb0,UIView 
0x7fa9c340b9d0,ViewController 
0x7fa9c3403c50,UIViewControllerWrapperView 
0x7fa9c340ee90,UINavigationTransitionView 
0x7fa9c5802d10,UILayoutContainerView 
0x7fa9c381ee00,UINavigationController 
0x7fa9c3609c40,UIWindow 
0x7fa9c3400020,UIApplication 
0x608000038900,AppDelegate 
2017-03-08 22:49:54.501 view[36189:410065] hide 
0x7fa9c36059f0,MyView 
0x7fa9c3407cb0,UIView 
0x7fa9c340b9d0,ViewController 
0x7fa9c3500bd0,UIView <----- not real hide 
2017-03-08 22:49:54.501 view[36189:410065] show 
0x7fa9c36059f0,MyView 
0x7fa9c3407cb0,UIView 
0x7fa9c340b9d0,ViewController 
0x7fa9c3500bd0,UIView 
0x7fa9c3403c50,UIViewControllerWrapperView 
0x7fa9c340ee90,UINavigationTransitionView 
0x7fa9c5802d10,UILayoutContainerView 
0x7fa9c381ee00,UINavigationController 
0x7fa9c3609c40,UIWindow 
0x7fa9c3400020,UIApplication 
0x608000038900,AppDelegate 
2017-03-08 22:49:54.501 view[36189:410065] show 
0x7fa9c35062f0,MyView 
0x7fa9c3505ae0,UIView 
0x7fa9c58030c0,ViewController 
0x7fa9c3506c10,_UIParallaxDimmingView 
0x7fa9c35022c0,UIView 
0x7fa9c3403c50,UIViewControllerWrapperView 
0x7fa9c340ee90,UINavigationTransitionView 
0x7fa9c5802d10,UILayoutContainerView 
0x7fa9c381ee00,UINavigationController 
0x7fa9c3609c40,UIWindow 
0x7fa9c3400020,UIApplication 
0x608000038900,AppDelegate 
2017-03-08 22:49:55.037 view[36189:410065] hide 
0x7fa9c36059f0,MyView 
0x7fa9c3407cb0,UIView 
0x7fa9c340b9d0,ViewController <----- real hide