iOS 简单代码实现强制键盘横屏显示

废话开篇:记录下 ViewController 在不设置横屏的情况下如何将键盘横屏显示。有朋友会问,直接设置屏幕横屏显示不就行了。先说一下应用场景:基于 uniapp 组件封装,也就是封装静态库,实现横屏浏览的的功能,因为 iOS 端只提供静态库,HBuilderX 再将 iOS 静态库进行 uni 远端编译,所以,至于对基座工程的权限修改基本是不可能,因此,会存在几个问题:1、 HBuilderX 项目开发人员可能是将 APP 朝向固定死。 2、横竖屏转换后会出现因为横屏键盘弹出后,再返回竖屏 ViewController 无法进行旋转为竖屏的BUG。作为库即便对之前的ViewController 进行方法交换,实现强制再转换为竖屏,但是成本及未知问题还是存在

一、横竖屏转换存在的 BUG

工程配置

image.png

BUG 描述

横屏界面弹出键盘后,再直接返回上一层时候,上一层 ViewController 无法自发的进行竖屏转换。注意看横、竖屏的提示文字。两个 ViewController 通过模态弹出。

屏幕录制2022-02-11 上午10.06.46.gif

解决方案

将竖屏展示 ViewControllerviewWillAppear 方法里添加强制转换的代码。前提是先设定竖屏 ViewController 支持的旋转方向。

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    //进行竖屏旋转
    if ([[UIDevice currentDevice] respondsToSelector: **@selector**(setOrientation:)]) {
              SEL selector = NSSelectorFromString(@"setOrientation:");
              NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
              [invocation setSelector:selector];
              [invocation setTarget:[UIDevice currentDevice]];
              int val = UIInterfaceOrientationPortrait;
              [invocation setArgument:&val atIndex:2];
              [invocation invoke];
    }
}

效果

屏幕录制2022-02-11 上午10.19.14.gif

这里在返回竖屏的时候,因为执行了屏幕方向设置逻辑,即使之前有横向键盘弹出的情况,竖屏也能正常展示了。

二、不旋转屏幕,仅将键盘横向实现效果

竖屏

Simulator Screen Shot - iPhone 11 - 2022-02-10 at 23.06.15_gaitubao_414x896.png

横屏

Simulator Screen Shot - iPhone 11 - 2022-02-10 at 23.07.48_gaitubao_414x896.png

这里并没有将 ViewController 进行横屏设置,只是当键盘弹出来时简单的修改了 UIRemoteKeyboardWindow 的旋转角度。

三、关键代码

view 进行90度旋转

self.view.transform = CGAffineTransformMakeRotation(M_PI_2);

textField 在开始编辑的代理方法里将 UIRemoteKeyboardWindow 旋转90度。

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSInteger windowCount = [[[UIApplication sharedApplication] windows] count];
            if(windowCount > 1){
                UIWindow *keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:(windowCount-1)];
                if ([keyboardWindow isKindOfClass:NSClassFromString(@"UIRemoteKeyboardWindow")]) {
                    keyboardWindow.bounds =CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width);
                    keyboardWindow.center = CGPointMake([[UIScreen mainScreen] bounds].size.width*0.5f,[[UIScreen mainScreen] bounds].size.height*0.5f);
                    keyboardWindow.transform = CGAffineTransformMakeRotation(M_PI_2);
           }
        }
    });
}

这里有个问题:

Simulator Screen Shot - iPhone 11 - 2022-02-10 at 23.14.08_gaitubao_414x896.png

就是文字选中部分 UIMenuController 并没有进行旋转。

可以先把它隐藏掉,单独创建一个 WSLUITextField 继承自 UITextField

添加一下代码:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    return NO;
}

Simulator Screen Shot - iPhone 11 - 2022-02-10 at 23.20.30_gaitubao_414x896.png

四、总结

为满足 uniapp 的某些功能而进行 iOS 静态库的编写,这里面确实存在一些难以消化的问题,即便是采取曲线救国策略,也很难做到尽善尽美。因为本身对 uniapp 的基座调试很不方便,即便是本地可以运行,但进行云端编译后安装包是否还是正常却存在未知数。uniapp 的开发由于可以对原生进行自定义扩展个人觉得还是很不错的,但是有些功能调试起来却不太容易,因为官方有的文档涵盖面比较少,解释也不是很详细。

随笔记录,大神勿笑[抱拳][抱拳][抱拳],如有更好的办法来实现在不进行横屏属性设置的情况下实现键盘横屏展示,希望大佬指点。