我意识到在iOS 8中不推荐使用didRotateFromInterfaceOrientation
;但是,我有一个需要与iOS7保持兼容的应用程序。我遇到的问题是,当设备旋转时(在这种情况下为iPad),此方法被调用两次。这发生在实际设备以及模拟器上。我只是在方法中放了一个NSLog来显示它。
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
NSLog(@"didRotateCalled");
}
我还检查了willRotateToInterfaceOrientation
,但是只有一次调用才能正常工作。
为什么didRotateFromInterfaceOrientation
方法每次轮换会被触发两次?
快速更新。我提出了一个断点,揭示了一些有趣的东西。此视图为UISplitviewcontroller
,看起来该方法首先针对UISplitviewcontroller
调用,然后调用UIViewController
。不知道为什么......
一些其他信息。我正在使用Storyboard一个用于iPhone和另一个iPad。 iPhone不使用splitViewController
。代码库是共享的,因此在prepareForSegue
我执行以下操作:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
splitViewController.delegate = segue.destinationViewController;
}
答案 0 :(得分:3)
我有答案。我刚刚下载了适用于iOS 7.1的模拟器,以便在最新的Xcode中使用。我发现在iOS 7.1下运行时不会调用viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
方法。但是,我还发现,我在两次旋转触发中描述的问题不会发生在iOS7中的willRotateToInterfaceOrientation
方法,但在iOS 8中也是如此。这是Apple的一个明显错误。
看起来我需要检测客户正在运行的操作系统版本,如果是iOS 8或更高版本,我将不会在willRotateToInterfaceOrientation
方法中执行任何代码。但是,我可以为iOS 8设备保留viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
方法,因为iOS 7会忽略此方法。
我不知道这对于splitviewcontrollers或iOS 7和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)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
方法,因为这将被iOS 7设备忽略,但将由iOS 8.x调用,大概在上面。
答案 1 :(得分:1)
我有同样的问题(虽然在我的情况下,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;
}
答案 2 :(得分:0)
我发现viewWillTransition
针对不同的UIViewController
个实例进行了两次调用。在第一次调用时,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
}
}