【发布时间】: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