我有下面的代码,当调用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
。基本上每当我点击其中一个textFields时,都会调用键盘的这个通知,并且keyboardWillShow
中的代码将会运行。我知道我放了if...let
个陈述,但我想知道为什么我这样做了。
我不确定我是如何得到此错误或如何调试它。是因为我是从模拟器运行的吗?
以下是打印notification.userInfo的内容:
可选([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])
答案 0 :(得分:3)
来自文档:
let UIKeyboardFrameEndUserInfoKey: String
描述
包含标识CGRect的CGRect的NSValue对象的键 屏幕坐标中键盘的结束帧
你的第二把钥匙:
let UIKeyboardAnimationDurationUserInfoKey: String
描述包含double的NSNumber对象的键 以秒为单位识别动画的持续时间。
所以你需要将第一个转换为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
}
答案 1 :(得分:2)
(如何解决你的问题清楚写在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的功能:“隐式类型转换_SwiftValue
回到Swift值”
太长了......
请勿在Swift 3中使用as AnyObject
投射