Ios 旋转时DidRotateFromInterface定向触发两次
我意识到,Ios 旋转时DidRotateFromInterface定向触发两次,ios,objective-c,Ios,Objective C,我意识到,didRotateFromInterfaceOrientation在iOS 8中不受欢迎;但是,我有一个应用程序需要与iOS7保持兼容。我遇到的问题是,当设备旋转时(本例中为iPad),此方法会被调用两次。这在实际设备上以及模拟器上都会发生。我只是在方法中添加了一个NSLog来显示这一点 -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
didRotateFromInterfaceOrientation
在iOS 8中不受欢迎;但是,我有一个应用程序需要与iOS7保持兼容。我遇到的问题是,当设备旋转时(本例中为iPad),此方法会被调用两次。这在实际设备上以及模拟器上都会发生。我只是在方法中添加了一个NSLog来显示这一点
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
NSLog(@"didRotateCalled");
}
我还检查了willRotateToInterfaceOrientation
,但只有一次调用才能正常工作
有没有想过为什么每次旋转都会触发两次didRotateFromInterfaceOrientation
方法
作为快速更新。我设置了一个断点,其中显示了一些有趣的内容。此视图是一个UISplitviewcontroller
,它看起来像是先为UISplitviewcontroller
调用方法,然后作为UIViewController
调用方法。不知道为什么
一些补充资料。我正在使用故事板,一个用于iPhone,另一个用于iPad。iPhone不使用splitViewController
。代码库是共享的,因此在prepareforsgue
中,我执行以下操作:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
splitViewController.delegate = segue.destinationViewController;
}
我有我的答案。我刚刚下载了iOS7.1模拟器,以便在最新的Xcode中使用。我发现在iOS 7.1下运行时,
viewwilltransitionosize:(CGSize)size with transitionocordinator:(id)coordinator
方法没有被调用。然而,我还发现,我描述的两次旋转触发的问题并没有发生在iOS7中的willrotateTocationInterfaceOrientation
方法中,而是再次发生在ios8中。这是苹果公司的一个明显缺陷
看起来我需要检测客户正在运行的操作系统版本,如果是iOS 8或更高版本,我不会让它在willRotateToInterfaceOrientation
方法中执行任何代码。但是,对于iOS 8设备,我可以将视图willTransitionOnSize:(CGSize)size与TransitionCoordinator:(id)coordinator
方法保留在其中,因为iOS 7将忽略此方法
我不知道这是否仅仅是SplitViewController的问题,还是所有在iOS 7和iOS 8之间使用旋转的视图方法的问题。如果你的应用程序没有覆盖这个方法,你永远不会知道。如果是这样,你将面对我在上面所做的一切。不太好
以下是我用来检查版本的代码:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if (NSFoundationVersionNumber == NSFoundationVersionNumber_iOS_7_1) // use this only for iOS7 devices as otherwise this fires twice under iOS8
{
...
}
}
我留下了-(void)viewwillTransitionOnSize:(CGSize)size with TransitionCoordinator:(id)coordinator
方法,因为这将被iOS 7设备忽略,但iOS 8.x和以上版本可能会调用 我也有同样的问题(不过在我的例子中,willRotate在iOS 8上也执行了两次)。我使用了以下解决方法:
BOOL _willRotate; // iVar for the state
// Methods that should be called from willRotate/didRotate (can be inline)
- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute
{
if(_willRotate) {
return NO;
}
_willRotate = YES;
return YES;
}
- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute
{
if(_willRotate) {
_willRotate = NO;
return YES;
}
return NO;
}
// Inside willRotate (return if shouldn't execute):
if(![self workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute]) {
return;
}
// Inside didRotate (return if shouldn't execute):
if(![self workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute]) {
return;
}
我发现针对不同的
UIViewController
实例调用了两次viewWillTransition
。第一次调用时,self是有效实例。但在第二次通话中,self无效<代码>viewDidLoad()未在此无效实例上调用。
我添加一个成员并在viewDidLoad
上设置值,然后检查self是否有效
class MyViewControler: UIViewController {
var last_width:CGFloat?
override func viewDidLoad() {
super.viewDidLoad()
print(" viewDidLoad self \(self) has address: \(Unmanaged.passUnretained(self).toOpaque())")
last_width = self.view.bounds.width
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
print(" viewWillTransition self \(self) has address: \(Unmanaged.passUnretained(self).toOpaque())")
// Bug? viewWillTransition called twice with diffent self instance, ignore second call
if (last_width == nil || last_width == size.width) {
return
}
last_width = size.width
}
}
从InterfaceOrientation打印
。您得到了什么?列出您正在使用的ViewController类,以及您在哪里实现了didRotateFromInterfaceOrientation
。您的方法可能是从不同的实例调用的,也可能是从类和超类中的代码调用的。主拆分是UITableViewController,而详细信息部分是UIViewController。当在主界面上选择一个单元格时,细节将被相应的内容“替换”。您可以在我的代码中看到PreReforSegue中的设置。此外,讨论中的didRotate方法位于详细视图中。作为测试,我快速将didRotate方法放入主拆分中,并在旋转时触发两次。