ios - inesperadamente encontrado nil mientras desenvuelve un valor opcional keyboardWillShow
swift swift3 (2)
(Cómo solucionar su problema está claramente escrito en la respuesta de Leo Dabus, así que trataré de explicar el error que estaba obteniendo antes de agregar el! ).
En Swift 3, as AnyObject
ha convertido en una de las operaciones más riesgosas. Está relacionado con la peor característica nueva llamada como id-as-Any .
En esta línea de tu código:
keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
El tipo de expresión notification.userInfo?[UIKeyboardFrameEndUserInfoKey]
es Any?
. Como ve, un tipo opcional Any?
no se debe convertir de manera segura a AnyObject
no opcional. Pero Swift 3 lo convierte con la creación de _SwiftValue
no opcional.
Puede verificar este comportamiento con la inserción de este código:
print(type(of: notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject))
Por lo tanto, está intentando aplicar .cgRectValue
no opcional a _SwiftValue
, lo que puede confundir la característica de Swift 3: "conversión de tipo implícita _SwiftValue
nuevo al valor de Swift".
Demasiado tiempo ...
NO utilizar as AnyObject
fundido as AnyObject
en Swift 3
Tengo este código debajo que se ejecuta cuando se llama al tecladoWillShowNotification:
func keyboardWillShow(_ notification: Notification) {
//ERROR IN THE LINE BELOW
keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
animaton = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as AnyObject).doubleValue
UIView.animate(withDuration: 0.4, animations: { () -> Void in
self.scrollView.frame.size.height = self.scrollViewHeight - self.keyboard.height
})
}
Recibo un error en la segunda línea que dice: unexpectedly found nil while unwrapping an Optional value
. Básicamente cada vez que hago clic en uno de los textFields se llamará a esta notificación para el teclado y se ejecutará el código en keyboardWillShow
. Sé que puse if...let
declaraciones, pero quiero saber por qué me estoy volviendo loco por esto.
No estoy seguro de cómo estoy obteniendo este error ni cómo depurarlo tampoco. ¿Es porque lo estoy ejecutando desde el simulador?
Esto es lo que imprime el notification.userInfo da:
Opcional ([AnyHashable ("UIKeyboardFrameEndUserInfoKey"): NSRect: {{0, 315}, {320, 253}}, AnyHashable ("UIKeyboardIsLocalUserInfoKey"): 1, AnyHashable ("UIKeyboardBoundsUserInfoKey"): NSRect: {{0, 0} , {320, 253}}, AnyHashable ("UIKeyboardAnimationCurveUserInfoKey"): 7, AnyHashable ("UIKeyboardCenterBeginUserInfoKey"): NSPoint: {160, 694.5}, AnyHashable ("UIKeyboardCenterEndUserInfoKey"): NSPoint: {160, 441.5}, AnyHashable (" UIKeyboardFrameBeginUserInfoKey "): NSRect: {{0, 568}, {320, 253}}, AnyHashable (" UIKeyboardAnimationDurationUserInfoKey "): 0.25])
De los documentos:
let UIKeyboardFrameEndUserInfoKey: String
Descripción
La clave para un objeto NSValue que contiene un CGRect que identifica el marco final del teclado en coordenadas de pantalla
Tu segunda clave:
let UIKeyboardAnimationDurationUserInfoKey: String
Descripción La clave para un objeto NSNumber que contiene un doble que identifica la duración de la animación en segundos.
Por lo tanto, debe convertir el primero a NSValue y el segundo a NSNumber:
func keyboardWillShow(_ notification: Notification) {
print("keyboardWillShow")
guard let userInfo = notification.userInfo else { return }
keyboard = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
animaton = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
// your code
}