keyboard ios9 uialertcontroller

keyboard - Mostrar UIAlertController sobre el teclado



ios9 (4)

use UIAlertController en lugar de UIActionSheet

En iOS 8 y versiones inferiores, se mostrará una UIActionSheet cuando se presente el teclado que presentará la hoja de acción sobre el teclado. Con iOS 9, este ya no es el caso.

En mi aplicación tenemos una funcionalidad de chat y queremos mostrar una acción sobre el teclado. Solíamos usar UIActionSheet que funcionó bien hasta iOS 8. En iOS 9, la hoja de acción está presente detrás del teclado. Intenté tanto con UIActionSheet como con UIAlertController .

Lo que queremos es una hoja de acción como en messages.app

Intenté colocar la hoja de acción en su propia ventana y reemplazar el canBecomeFirstResponder que acaba de hacer desaparecer el teclado.


Basado en la respuesta de Leo Natan, he creado una extensión Swift para presentar una hoja de alerta sobre el teclado.

En mi breve prueba, la ventana de alerta se desasigna después de que se descarta la alerta, creo que porque no hay una referencia fuerte fuera de la alerta. Esto significa que no hay necesidad de ocultarlo o desasignarlo en sus 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 } }


Implementé exactamente esto en nuestra aplicación. El truco es hacer que el controlador de alerta aparezca en una ventana diferente. Así es como lo UIActionSheet implementación de UIActionSheet , y funciona muy bien en iOS 8, pero en 9, Apple ha movido la implementación del teclado a una ventana que tiene un nivel de ventana muy alto (10000000). La solución es dar a su ventana de alerta un nivel de ventana aún mayor (como un valor doble personalizado, sin usar las constantes proporcionadas).

Cuando utilice una ventana personalizada que tendrá transparencia, asegúrese de leer mi respuesta aquí , con respecto al color de fondo, para evitar que la ventana se vuelva negra durante las transiciones de rotación.

_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];


La respuesta proporcionada por Leo está rota a partir de iOS 11, porque Apple ahora le impide configurar windowLevel por encima de 10000000 . Una solución es implementar una UIWindow personalizada y anular el receptor 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];

Este enfoque debe ser compatible con versiones anteriores, pero no ha probado todas las versiones conocidas. ¡Feliz hacking!