意外地发现零,而解包可选值keyboardWillShow
我有下面的代码在keyboardWillShowNotification被调用时运行:
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
。 基本上每当我点击其中一个textField时,键盘的这个通知就会被调用, keyboardWillShow
的代码将会运行。 我知道, if...let
我发言,但我想知道为什么我没有这个。
我不知道我是如何得到这个错误或如何debugging它。 是因为我是从模拟器运行它吗?
以下是打印notification.userInfo给出的内容:
NSRect:{{0,315},{320,253}},AnyHashable(“UIKeyboardIsLocalUserInfoKey”):1,AnyHashable(“UIKeyboardBoundsUserInfoKey”):NSRect:{{0,0} (“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
描述
包含CGRect的NSValue对象的关键字,用于在屏幕坐标中标识键盘的结束帧
你的第二个关键:
let UIKeyboardAnimationDurationUserInfoKey: String
描述包含double的NSNumber对象的键,以秒为单位标识animation的持续时间。
所以你需要将第一个投给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 }
(如何解决你的问题显然写在狮子座达布斯的答案,所以我会尝试解释我得到的错误之前,我添加!
在Swift 3中, as AnyObject
已经成为风险最大的操作之一。 这与称为id-as-Any的最糟糕的新function有关。
在你的代码的这一行中:
keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
expression式notification.userInfo?[UIKeyboardFrameEndUserInfoKey]
的types是Any?
。 正如你看到的,一个可选typesAny?
不应安全地转换为非可选AnyObject
。 但Swift 3转换它创build非可选的_SwiftValue
。
您可以通过插入以下代码来检查此行为:
print(type(of: notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject))
所以,你试图将非可选的链接.cgRectValue
应用于_SwiftValue
,这可能会使Swift 3的特性“隐式types转换_SwiftValue
返回Swift值”。
太久了…
不要在Swift 3中使用as AnyObject
投射