在展开可选值 keyboardWillShow 时意外发现 nil
unexpectedly found nil while unwrapping an Optional value keyboardWillShow
我有以下代码,当调用 keyboardWillShowNotification 时 运行s:
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
})
}
我在第二行收到一条错误消息:unexpectedly found nil while unwrapping an Optional value
。基本上每当我单击其中一个文本字段时,都会调用此键盘通知,并且 keyboardWillShow
中的代码将 运行。我知道我放了 if...let
语句,但我想知道为什么我为此得到 nil。
我不确定我是如何得到这个错误的,也不知道如何调试它。是因为我 运行 从模拟器上安装它吗?
这是打印 notification.userInfo 的结果:
Optional([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])
来自文档:
let UIKeyboardFrameEndUserInfoKey: String
Description
The key for an NSValue object containing a CGRect that identifies the
end frame of the keyboard in screen coordinates
你的第二把钥匙:
let UIKeyboardAnimationDurationUserInfoKey: String
Description The key for an NSNumber object containing a double that
identifies the duration of the animation in seconds.
因此您需要将第一个转换为 NSValue,将第二个转换为 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
}
(Leo Dabus 的回答中清楚地写明了如何解决您的问题,所以我将尝试 解释我在添加 ! 之前遇到的错误。)
在Swift 3、as AnyObject
成为了风险最高的操作之一。
它与称为 id-as-Any.
的最糟糕的新功能有关
在你的这行代码中:
keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
表达式 notification.userInfo?[UIKeyboardFrameEndUserInfoKey]
的类型是 Any?
。如您所见,不应将可选类型 Any?
安全地转换为非可选类型 AnyObject
。但是 Swift 3 通过创建非可选 _SwiftValue
.
来转换它
您可以通过插入以下代码来检查此行为:
print(type(of: notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject))
因此,您正在尝试将非可选链接 .cgRectValue
应用于 _SwiftValue
,这可能会混淆 Swift 3 的功能:"implicit type conversion _SwiftValue
back to the Swift value".
时间太长了...
不要在 Swift 中使用 as AnyObject
转换 3
我有以下代码,当调用 keyboardWillShowNotification 时 运行s:
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
})
}
我在第二行收到一条错误消息:unexpectedly found nil while unwrapping an Optional value
。基本上每当我单击其中一个文本字段时,都会调用此键盘通知,并且 keyboardWillShow
中的代码将 运行。我知道我放了 if...let
语句,但我想知道为什么我为此得到 nil。
我不确定我是如何得到这个错误的,也不知道如何调试它。是因为我 运行 从模拟器上安装它吗?
这是打印 notification.userInfo 的结果:
Optional([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])
来自文档:
let UIKeyboardFrameEndUserInfoKey: String
Description
The key for an NSValue object containing a CGRect that identifies the end frame of the keyboard in screen coordinates
你的第二把钥匙:
let UIKeyboardAnimationDurationUserInfoKey: String
Description The key for an NSNumber object containing a double that identifies the duration of the animation in seconds.
因此您需要将第一个转换为 NSValue,将第二个转换为 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
}
(Leo Dabus 的回答中清楚地写明了如何解决您的问题,所以我将尝试 解释我在添加 ! 之前遇到的错误。)
在Swift 3、as AnyObject
成为了风险最高的操作之一。
它与称为 id-as-Any.
在你的这行代码中:
keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
表达式 notification.userInfo?[UIKeyboardFrameEndUserInfoKey]
的类型是 Any?
。如您所见,不应将可选类型 Any?
安全地转换为非可选类型 AnyObject
。但是 Swift 3 通过创建非可选 _SwiftValue
.
您可以通过插入以下代码来检查此行为:
print(type(of: notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject))
因此,您正在尝试将非可选链接 .cgRectValue
应用于 _SwiftValue
,这可能会混淆 Swift 3 的功能:"implicit type conversion _SwiftValue
back to the Swift value".
时间太长了...
不要在 Swift 中使用 as AnyObject
转换 3