【问题标题】:willMoveToWindow is called twicewillMoveToWindow 被调用两次
【发布时间】:2016-04-01 18:30:50
【问题描述】:

我正在调整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

编辑 控制台

    [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>

【问题讨论】:

  • 你不能检查view.window吗?为什么需要调酒?调酒很糟糕。
  • 那不相关 - 这只是一个旁注。问题是它被调用了两次 -
  • 这对我来说很有意义。 1. ViewDidLoad 添加子视图 2. 视图添加到窗口。使用该命令链,您必须获得两次 willMoveToWindow 调用。您可能想使用一些标志或其他东西来注册相关事件。
  • 它是同一个实例 - 不是不同的实例:(已经在屏幕上的那个)它被移出屏幕并且 willMoveToWindow: 被调用了两次。一次使用 nil,然后使用原始窗口
  • [RandomView willMoveToWindow:] [RandomView didMoveToWindow] [RandomView willMoveToWindow:] [RandomView willMoveToWindow:] [RandomView didMoveToWindow]

标签: ios objective-c uiview uikit swizzling


【解决方案1】:

我也遇到了同样的问题

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

但我认为 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

【讨论】:

    猜你喜欢
    • 2012-05-05
    • 2017-01-19
    • 2014-02-04
    • 2016-12-13
    • 2016-01-30
    • 2015-12-20
    • 2019-04-04
    • 2016-02-25
    • 1970-01-01
    相关资源
    最近更新 更多