在键盘上显示UIAlertController

rck*_*nes 16 keyboard uialertcontroller ios9

在iOS 8及更低版本中显示UIActionSheet何时呈现键盘将在键盘上显示操作表.对于iOS 9,情况已不再如此.

在我的应用程序中,我们有一个聊天功能,并希望该节目通过键盘进行操作.我们过去常常使用UIActionSheet哪种工作正常,直到iOS 8.在iOS 9中,操作表存在于键盘后面.我都试过UIActionSheetUIAlertController.

我们想要的是一个像messages.app中的动作表 消息应用中的操作表.

我已经尝试将动作表放在它自己的窗口中并覆盖canBecomeFirstResponder,这使得键盘消失了.

Leo*_*ica 30

我在我们的应用程序中实现了这一点.诀窍是让警报控制器出现在不同的窗口上.这就是UIActionSheet实现的方式,并且在iOS 8上运行良好,但在9月,Apple已将键盘实现移至窗口级别非常高(10000000)的窗口.修复是为您的警报窗口提供更高的窗口级别(作为自定义double值,而不是使用提供的常量).

当使用具有透明度的自定义窗口时,请务必在此处阅读我的答案,关于背景颜色,以防止窗口在旋转过渡期间变黑.

_alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_alertWindow.rootViewController = [UIViewController new];
_alertWindow.windowLevel = 10000001;
_alertWindow.hidden = NO;
_alertWindow.tintColor = [[UIWindow valueForKey:@"keyWindow"] tintColor];

__weak __typeof(self) weakSelf = self;

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Test" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    weakSelf.alertWindow.hidden = YES;
    weakSelf.alertWindow = nil;
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Test" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    weakSelf.alertWindow.hidden = YES;
    weakSelf.alertWindow = nil;
}]];

[_alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 谢谢,这样一个简单的解决方案,至少有一段时间,直到这个价值再次发生变化.;) (2认同)

Emi*_*ols 6

从iOS 11开始,Leo提供的答案已经破解,因为Apple现在阻止您在上面设置windowLevel 10000000.修复是实现自定义UIWindow并覆盖windowLevel接收器:

@interface TopWindow : UIWindow @end

@implementation TopWindow
- (UIWindowLevel) windowLevel {
    return 20000000.000;
}
@end

// usage:
UIWindow* w = [[TopWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
w.rootViewController = [UIViewController new];
w.hidden = NO;

[w.rootViewController presentViewController:yourActionSheetController animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

此方法应向后兼容,但尚未测试所有已知版本.快乐的黑客!


Kyl*_*our 5

根据Leo Natan的回答,我创建了一个Swift扩展程序,用于在键盘上显示警报表。

在我的简短测试中,警报被关闭后,alertWindow会被释放,我相信是因为在警报之外没有对它的强烈引用。这意味着无需在UIAlertActions中隐藏或取消分配它。

extension UIAlertController {

    func presentOverKeyboard(animated: Bool, completion: (() -> Void)?) {

        let alertWindow = UIWindow(frame: UIScreen.mainScreen().bounds)

        // If you need a white/hidden/other status bar, use an appropriate VC.
        // You may not need a custom class, and you can just use UIViewController()
        alertWindow.rootViewController = whiteStatusBarVC()

        alertWindow.windowLevel = 10000001
        alertWindow.hidden = false

        // Set to a tint if you'd like
        alertWindow.tintColor = UIColor.greenColor()

        alertWindow.rootViewController?.presentViewController(self, animated: animated, completion: completion)
    }
}

private class whiteStatusBarVC: UIViewController {
    private override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .LightContent
    }
}
Run Code Online (Sandbox Code Playgroud)