2015-12-27 1 views
3

Я swizzling willMoveToWindow:, и я столкнулся с проблемой, когда его дважды вызывали на представления.willMoveToWindow называется дважды

Когда новый контроллер представления выталкивается на UINavigationController,

willMoveToWindow: вызывается на существующем виде с nil значения (имеет смысл, поскольку вид двигается закадровым)

По истечению этого времени метода willMoveToWindow: вызывается снова, но теперь с оригинальным окном.

Моя первая мысль, что swizzling и вызывая 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'? Зачем вам нужно подпевать? Swizzling - это плохо. – 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 
Смежные вопросы