iOS 8/7 UIWindow存在UIWindowLevelStatusBar旋转问题
我正在尝试添加一个带有iOS 8/7 UIWindow存在UIWindowLevelStatusBar旋转问题,ios,uiwindow,Ios,Uiwindow,我正在尝试添加一个带有UIWindowLevelStatusBarlevel的UIWindow。它在ipad上以肖像模式工作非常完美,但在旋转设备后,它就乱七八糟了 在iOS 7.x上,除了上下颠倒之外,所有旋转都很好,而在iOS 8.x上,只有纵向模式是好的,所有其他方向都是混乱的。你知道怎么解决吗 CGRect frame = [UIApplication sharedApplication].statusBarFrame; self.statusWindow = [[UIWindow al
UIWindowLevelStatusBar
level的UIWindow。它在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答案的修改:如果将旋转放在视图控制器的
willrotateTointerfaceooritation
方法中,则执行旋转效果会更好。这样,仅当设备旋转到应用程序构建设置的General->Deployment Info部分中指定的支持方向之一时,才会应用旋转。作为额外的奖励,您可以访问旋转动画的持续时间。只需确保在视图控制器中有对模式窗口的引用
无论支持什么方向,只要屏幕方向改变,就会触发UIDeviceOrientationIDChangeNotification
通知。这可能导致不受欢迎的行为
下面是一个例子:
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解决方案(也需要如上所示的转换):
但是,它不适用于iOS9测试版。这是处理定向支持的高度随机的方法。您甚至不应该考虑转换任何东西,因为只要您正确设置
rootViewController
属性,UIWindow
就可以并将为您处理所有事情。代码中缺少一些东西,显示与您的状态窗口相关的所有代码。为了澄清,此代码将在状态栏上设置另一个uiwindow。因此,没有rootviewcontroller。如果我不转换uiwindow,它将保持纵向模式,在iOS 7和iOS 8上都不会旋转,因此必须手动旋转。如果您知道更好的方法,请共享。旋转确实有效,但uiwindow未根据屏幕方向正确定位和调整大小。无论如何,谢谢你的努力。
UIScreen *screen = [UIScreen mainScreen];
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
if ([screen respondsToSelector:@selector(fixedCoordinateSpace)])
{
[self setFrame:[screen.coordinateSpace convertRect:statusBarFrame toCoordinateSpace:screen.fixedCoordinateSpace]];
}