iOS 8.3 键盘方向错误
iOS 8.3 keyboard orientation bug
我遇到了一个奇怪的 iOS 8.3 问题,该问题显示键盘方向错误(视图控制器处于横向模式,但键盘显示为纵向模式):
我可以按照以下步骤触发此问题:
创建 2 UIViewController
子类:ViewControllerA
和 ViewControllerB
在ViewControllerA
中实现supportedInterfaceOrientations
和returnUIInterfaceOrientationMaskPortrait
在ViewControllerB
中实现supportedInterfaceOrientations
和returnUIInterfaceOrientationMaskLandscape
创建一个名为 NavigationController
的 UINavigationController
子类,实现 supportedInterfaceOrientations
和 return [self.topViewController supportedInterfaceOrientations]
(我这样做是因为我想要防止 NavigationController 和它的 rootVC 旋转)
使用 NavigationController
作为应用程序的初始视图控制器,将 ViewControllerA
设置为 NavigationController
的 rootViewContrller
启动应用程序,ViewControllerA
将显示在肖像中。在 ViewControllerA
上显示一个按钮,按下按钮将使用 presentViewController:animated:completion
显示 ViewControllerB
ViewControllerB
会出现在横向;在 ViewControllerB
上显示一个文本字段,点击文本字段将触发键盘,但键盘是纵向模式,就像上图一样。
PS。您可以下载 运行 Xcode 项目 on github
这个问题似乎只出现在 iOS 8.3 上。难道我做错了什么 ?或者这可能只是 iOS 的另一个错误?
顺便说一句,如果您直接显示 ViewControllerA
而没有 ViewController
,则不会发生此问题。因此,如果这是 iOS 的错误,我怎样才能避免子类化 UINavigationController
但仍然保持 ViewControllerA
是 UINavigationController
的 rootViewController 旋转。
更新:这个错误仍然出现在 iOS 8.4 上,我在 2015 年 6 月 17 日发布了一个错误报告并得到了苹果的回复,他们说它已经在最新的 iOS 9 beta 中得到解决.
我问过技术支持,他们说
Our engineers have reviewed your request and have determined that this would be best handled as a bug report.
看来确认是系统bug
而我目前的解决方案是在ViewControllerA和ViewControllerB之间添加一个ViewControllerC(同时支持纵向和横向模式):ViewControllerA应该为ViewControllerC呈现动画,在ViewControllerC出现之后,呈现ViewControllerB而没有动画。
为了使过渡看起来自然,您可以将与 ViewControllerB 相同的背景颜色设置为 ViewControllerC,或者拍摄 ViewControllerB 的屏幕截图并将其作为背景图像添加到 ViewControllerC。
这不是一个完美的解决方案,对于用户来说,他们可能会发现 ViewControllerB 需要更多的时间来加载。
我们通过诱使设备认为它旋转到不同的方向然后旋转到其预期方向来解决这个问题。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.segmentedControl.selectedSegmentIndex = 0;
if(!self.rotatingForDismissal)
{
[self.tableNumberTextField becomeFirstResponder];
}
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.3"))
{
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeLeft) forKey:@"orientation"];
[[UIDevice currentDevice] setValue:@(self.interfaceOrientation) forKey:@"orientation"];
}
}
我能够使用以下方法使键盘正确显示。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (SYSTEM_VERSION_GREATER_THAN(@"7.1") && SYSTEM_VERSION_LESS_THAN(@"9.0"))
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];
[[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"];
}
}
请注意,使用 UIDeviceOrientationUnknown
不会导致副作用,例如不适当的视图自动旋转。
我遇到了一个奇怪的 iOS 8.3 问题,该问题显示键盘方向错误(视图控制器处于横向模式,但键盘显示为纵向模式):
我可以按照以下步骤触发此问题:
创建 2
UIViewController
子类:ViewControllerA
和ViewControllerB
在
ViewControllerA
中实现supportedInterfaceOrientations
和returnUIInterfaceOrientationMaskPortrait
在
ViewControllerB
中实现supportedInterfaceOrientations
和returnUIInterfaceOrientationMaskLandscape
创建一个名为
NavigationController
的UINavigationController
子类,实现supportedInterfaceOrientations
和 return[self.topViewController supportedInterfaceOrientations]
(我这样做是因为我想要防止 NavigationController 和它的 rootVC 旋转)使用
NavigationController
作为应用程序的初始视图控制器,将ViewControllerA
设置为NavigationController
的rootViewContrller
启动应用程序,
ViewControllerA
将显示在肖像中。在ViewControllerA
上显示一个按钮,按下按钮将使用presentViewController:animated:completion
显示 ViewControllerB
会出现在横向;在ViewControllerB
上显示一个文本字段,点击文本字段将触发键盘,但键盘是纵向模式,就像上图一样。
ViewControllerB
PS。您可以下载 运行 Xcode 项目 on github
这个问题似乎只出现在 iOS 8.3 上。难道我做错了什么 ?或者这可能只是 iOS 的另一个错误?
顺便说一句,如果您直接显示 ViewControllerA
而没有 ViewController
,则不会发生此问题。因此,如果这是 iOS 的错误,我怎样才能避免子类化 UINavigationController
但仍然保持 ViewControllerA
是 UINavigationController
的 rootViewController 旋转。
更新:这个错误仍然出现在 iOS 8.4 上,我在 2015 年 6 月 17 日发布了一个错误报告并得到了苹果的回复,他们说它已经在最新的 iOS 9 beta 中得到解决.
我问过技术支持,他们说
Our engineers have reviewed your request and have determined that this would be best handled as a bug report.
看来确认是系统bug
而我目前的解决方案是在ViewControllerA和ViewControllerB之间添加一个ViewControllerC(同时支持纵向和横向模式):ViewControllerA应该为ViewControllerC呈现动画,在ViewControllerC出现之后,呈现ViewControllerB而没有动画。
为了使过渡看起来自然,您可以将与 ViewControllerB 相同的背景颜色设置为 ViewControllerC,或者拍摄 ViewControllerB 的屏幕截图并将其作为背景图像添加到 ViewControllerC。
这不是一个完美的解决方案,对于用户来说,他们可能会发现 ViewControllerB 需要更多的时间来加载。
我们通过诱使设备认为它旋转到不同的方向然后旋转到其预期方向来解决这个问题。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.segmentedControl.selectedSegmentIndex = 0;
if(!self.rotatingForDismissal)
{
[self.tableNumberTextField becomeFirstResponder];
}
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.3"))
{
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeLeft) forKey:@"orientation"];
[[UIDevice currentDevice] setValue:@(self.interfaceOrientation) forKey:@"orientation"];
}
}
我能够使用以下方法使键盘正确显示。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (SYSTEM_VERSION_GREATER_THAN(@"7.1") && SYSTEM_VERSION_LESS_THAN(@"9.0"))
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];
[[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"];
}
}
请注意,使用 UIDeviceOrientationUnknown
不会导致副作用,例如不适当的视图自动旋转。