处理旋转时更改的 iOS 键盘布局

Posted

技术标签:

【中文标题】处理旋转时更改的 iOS 键盘布局【英文标题】:Dealing with changing iOS keyboard layout upon rotation 【发布时间】:2015-01-08 11:13:16 【问题描述】:

根据设备的方向,我的键盘有两种略有不同的布局。当我第一次加载键盘时,它看起来不错。这是纵向版本:

初始约束设置发生在(UIInputViewController 子类的)-viewDidLoad 中

portraitConstraints = [self constraintsForOrientation:UIInterfaceOrientationPortrait];
landscapeConstraints = [self constraintsForOrientation:UIInterfaceOrientationLandscapeRight];

[self.view addConstraints:portraitConstraints];
[self.view addConstraints:landscapeConstraints];

if ([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) 
    [NSLayoutConstraint deactivateConstraints:landscapeConstraints];
 else 
    [NSLayoutConstraint deactivateConstraints:portraitConstraints];

这部分工作正常,因为无论初始方向如何,它都能正确加载。但是,一旦我旋转设备,一切都会出错。

然后回到纵向:

作为参考,正确的横向版本如下所示:

我将 -updateViewConstraints 中的约束更新如下:

- (void)updateViewConstraints 
    if ([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) 
        [NSLayoutConstraint deactivateConstraints:landscapeConstraints];
        [NSLayoutConstraint activateConstraints:portraitConstraints];
     else 
        [NSLayoutConstraint deactivateConstraints:portraitConstraints];
        [NSLayoutConstraint activateConstraints:landscapeConstraints];
    

    [super updateViewConstraints];

似乎在视图更改后它突然占据了超过全屏的空间,而不仅仅是键盘区域。有什么想法可以解决这个问题吗?谢谢。

【问题讨论】:

不确定,但可能是 autlayout 的情况,我曾经坚持使用简陋的键盘设计,所以我使用 autolayout,它可能会有所帮助 我认为将屏幕宽度与高度进行比较并不是最好的办法。相反,请尝试访问状态栏方向,例如 [[UIApplication sharedApplication] statusBarOrientation]. Or you could try to get the orientation of the device like this '[[UIDevice currentDevice] orientation] 另外,在我看来,您的限制是让“0x”按钮、空格按钮和返回按钮在纵向上具有固定宽度,而地球占据了其余部分。然后,我猜你已经应用了纵横比,这可以理解第一个“错误”键盘的外观。 @SKT 你推荐我使用还是不使用自动布局?我不确定 IB 之外的默认值是什么。 @mbm29414 我正在使用宽度/高度比较,因为您无法在应用扩展程序中检查 UIDevice 方向,并且当设备由于使用加速度计而平放时,statusBarOrientation 有时会返回未知响应.但我已将 NSLogs 放入我目前的操作方式中,它工作正常 - 当它改变时总是打印出正确的方向。 【参考方案1】:

该问题似乎与以某种方式隐式覆盖包含键盘的视图的高度有关。虽然我没有看到任何会强制调整容器视图大小的东西,但显式设置容器视图的高度会恢复到良好的、可重现的结果。

我想到了从Apple's App Extension Programming Guide: Custom Keyboard 手动限制键盘高度的想法。

具体来说,相关信息是这样的:

您可以使用自动布局调整自定义键盘主视图的高度。默认情况下,自定义键盘的大小会根据屏幕大小和设备方向与系统键盘匹配。自定义键盘的宽度始终由系统设置为等于当前屏幕宽度。要调整自定义键盘的高度,请更改其主视图的高度约束。

以下代码行显示了如何定义和添加这样的约束:

CGFloat _expandedHeight = 500;
NSLayoutConstraint *_heightConstraint = 
[NSLayoutConstraint constraintWithItem: self.view 
                             attribute: NSLayoutAttributeHeight 
                             relatedBy: NSLayoutRelationEqual 
                                toItem: nil 
                             attribute: NSLayoutAttributeNotAnAttribute 
                            multiplier: 0.0 
                              constant: _expandedHeight];
[self.view addConstraint: _heightConstraint];

注意

ios 8.0 中,您可以在主视图最初在屏幕上绘制后随时调整自定义键盘的高度。

以下是基于此信息的模板答案中的重要方法:

- (void)updateViewConstraints 
    if (self.keyboardHeightConstraint == nil) 
        // Just starting with SOME value for the height
        self.keyboardHeightConstraint =
        [NSLayoutConstraint constraintWithItem:self.view
                                     attribute:NSLayoutAttributeHeight
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:nil
                                     attribute:NSLayoutAttributeNotAnAttribute
                                    multiplier:0.0f
                                      constant:500.0f];
        [self.view addConstraint:self.keyboardHeightConstraint];
    
    // Obviously, these values will be changed based on device AND orientation
    // These are bogus values...
    if ([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) 
        self.keyboardHeightConstraint.constant  = 300.0f;
        [NSLayoutConstraint deactivateConstraints:self.landscapeConstraints];
        [NSLayoutConstraint activateConstraints:self.portraitConstraints];
     else 
        self.keyboardHeightConstraint.constant  = 400.0f;
        [NSLayoutConstraint deactivateConstraints:self.portraitConstraints];
        [NSLayoutConstraint activateConstraints:self.landscapeConstraints];
    
    [super updateViewConstraints];

【讨论】:

以上是关于处理旋转时更改的 iOS 键盘布局的主要内容,如果未能解决你的问题,请参考以下文章

更改键盘通知上的视图布局(Swift、iOS)

旋转时更改自定义键盘的高度

iOS 8 自定义键盘自动布局键

键盘显示时更改自动布局常量

iOS - 子视图不使用帧更改进行动画处理

更改键盘挂钩回调中的键盘布局