2015-12-27 140 views
3

我在調用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

回答

0

我也面臨着同樣的問題

但通過響應者鏈查找視圖層次結構後,有一個小的不同的可以檢查。我不確定這是否安全。

但我認爲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