具有UIWindowLevelStatusBar旋转问题的iOS 8/7 UIWindow

我试图添加UIWindow与UIWindowLevelStatusBar级别。 它在ipad完美的肖像模式工作,但旋转设备后,它搞砸了。

在iOS 7.x中,除了颠倒以外,所有的旋转都很好,而在iOS 8.x上,只有肖像模式很好,所有其他的方向都搞砸了。 任何想法如何解决?

 CGRect frame = [UIApplication sharedApplication].statusBarFrame; self.statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, 20)]; UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; CGRect frame = [UIApplication sharedApplication].statusBarFrame; CGAffineTransform test = [self transformForOrientation:orientation]; [self.statusWindow setWindowLevel:UIWindowLevelStatusBar]; [self.statusWindow setHidden:NO]; - (CGAffineTransform)transformForOrientation:(UIInterfaceOrientation)orientation { switch (orientation) { case UIInterfaceOrientationLandscapeLeft: return CGAffineTransformMakeRotation(-DEGREES_TO_RADIANS(90.0f)); case UIInterfaceOrientationLandscapeRight: return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90.0f)); case UIInterfaceOrientationPortraitUpsideDown: return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180.0f)); case UIInterfaceOrientationPortrait: default: return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0.0f)); } } 

在你的UIWindow子类的init方法中,观察这个通知:

 // Rotation Notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil]; self.baseT = self.transform; 

那么方法本身:

 - (void)didChangeOrientation:(NSNotification *)n { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; switch (orientation) { case UIInterfaceOrientationPortrait: self.transform = CGAffineTransformRotate(self.baseT, 0); break; case UIInterfaceOrientationPortraitUpsideDown: self.transform = CGAffineTransformRotate(self.baseT, M_PI); break; // Home button on left case UIInterfaceOrientationLandscapeLeft: self.transform = CGAffineTransformRotate(self.baseT, -M_PI_2); break; case UIInterfaceOrientationLandscapeRight: self.transform = CGAffineTransformRotate(self.baseT, M_PI_2); break; default: self.transform = CGAffineTransformMakeRotation(0); break; } } 

根据您的实施情况,您可能还必须确保框架不会更改。 另外,在类的dealloc方法中,停止收听通知。

作为对@ dezinezync答案的修改:如果将其放入视图控制器的willRotateToInterfaceOrientation方法中,执行旋转将会更好。 这样,只有当设备旋转到应用程序构build设置的“常规” – >“部署信息”部分中指定的支持方向之一时,才会应用旋转。 作为额外的奖励,您可以访问旋转animation的持续时间。 只要确保在视图控制器中有对模态窗口的引用。

UIDeviceOrientationDidChangeNotification通知在屏幕方向更改时触发,无论支持哪个方向。 这可能会导致不希望的行为。

这是一个例子:

 UIWindow *modalWindow; // Initialize your modal window somewhere in your code // ... - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; // Make sure the modalWindow exists if (modalWindow != nil) { // Animate the modal window's rotation [UIView animateWithDuration:duration animations:^{ [self rotateModal:modalWindow]; }]; } } - (void)rotateModal:(UIWindow*)window { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; switch (orientation) { case UIInterfaceOrientationPortrait: window.transform = CGAffineTransformRotate(self.baseT, 0); break; case UIInterfaceOrientationPortraitUpsideDown: window.transform = CGAffineTransformRotate(self.baseT, M_PI); break; // Home button on left case UIInterfaceOrientationLandscapeLeft: window.transform = CGAffineTransformRotate(self.baseT, -M_PI_2); break; case UIInterfaceOrientationLandscapeRight: window.transform = CGAffineTransformRotate(self.baseT, M_PI_2); break; default: window.transform = CGAffineTransformMakeRotation(0); break; } } 

我只是在一个横向的应用程序上做了这样的事情,我最终通过将所有内容移动到了willRotateToInterfaceOrientation方法来正常工作。

iOS8的解决scheme(需要如上所示的变换):

 UIScreen *screen = [UIScreen mainScreen]; CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; if ([screen respondsToSelector:@selector(fixedCoordinateSpace)]) { [self setFrame:[screen.coordinateSpace convertRect:statusBarFrame toCoordinateSpace:screen.fixedCoordinateSpace]]; } 

但是,它不适用于iOS9testing版。