[英]UIView animation does not work after a keyboard notification
当iOS设备旋转并按下键盘时,NotificationCenter将发送UIKeyboardWillChangeFrame-notification。 我正在尝试在那时开始自定义动画。 这是行不通的。
我正在尝试启动布局约束动画,但是我不能使用任何自定义动画持续时间,因为它在某种程度上已被系统覆盖。 我将始终获得与键盘上下移动动画匹配的持续时间。 在这种情况下,如何使用自己的动画时长。
下面是我期望的行为的代码示例:
@objc func keyboardWillChange(_ notification: NSNotification) {
let keyboardFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
self.textFieldBottomContstrain.constant = -keyboardFrame.height
UIView.animate(withDuration: myOwnDuration) {
self.view.layoutIfNeeded()
}
}
更新资料
经过一些测试,我发现了一个非常简单的解决方案,尽管对我来说有点麻烦。
但是无论如何,在UIView.animate-block之前只添加两行代码似乎可以重置自动动画参数,而我自己的参数可以再次使用。 这是我的工作补充:
UIView.setAnimationsEnabled(false)
UIView.setAnimationsEnabled(true)
更新2
马特提供的最佳解决方案。 有一种适当的方法可以覆盖运行时设置的原始动画持续时间: https : //developer.apple.com/documentation/uikit/uiviewanimationoptions/1622434-overrideinheritedduration
这里的问题是,当调用keyboardWillChange
时,您已经在一个看不见的动画块中,该动画块由运行时提供以动画化键盘的运动。 因此:
您无需说UIView.animate
,因为您在此处所做的任何可设置动画的操作都将被动画化。
如果您确实说UIView.animate
,则您的duration
将被忽略,因为它是从周围的隐式动画块继承而来的,除非您添加了关闭该继承的option
: https : //developer.apple.com/documentation/uikit/uiviewanimationoptions / 1622434-覆盖继承的持续时间
你不应该碰到self.view
的位置; 这不是你的看法。 如果需要在有键盘的同时滑动界面,请给self.view
完整的子视图并进行滑动。
试试这个代码。
UIView.animate(withDuration: 0.3, animations: {
self.view.layoutIfNeeded();
self.view.layoutSubviews()
}, completion: {(value: Bool) in
});
我可以为您提供这种方法。
1)添加结构:
struct HeightStruct {
var height: CGFloat
}
2)添加变量:
var heightStruct: HeightStruct = .init(height: 0)
3)观察者方法:
@objc func keyboardWillShow(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
DispatchQueue.main.async {
self.heightStruct.height = keyboardHeight
self.changeTextFieldPosition()
}
}
}
4)添加changeTextFieldPosition
方法:
func changeTextFieldPosition() {
UIView.animate(withDuration: 5.0) {
self. textFieldBottomContstrain.constant = - self.heightStruct.height
self.view.layoutIfNeeded()
}
}
看起来很丑,但是行得通。
1.在viewDidLoad()中注册键盘“隐藏和显示通知”
NotificationCenter.default.addObserver(self, selector:
#selector(keyBoardWillShow(notification:)), name:
.UIKeyboardWillShow , object: nil)
NotificationCenter.default.addObserver(self, selector:
#selector(keyBoardWillHide(notification:)), name: .UIKeyboardWillHide
, object: nil)
2.键盘隐藏和显示时调用
@objc func keyBoardWillShow(notification: NSNotification){
adjustInsetForKeyBoards(show: true, notification: notification)
}
@objc func keyBoardWillHide(notification: NSNotification){
adjustInsetForKeyBoards(show: false, notification: notification)
}
3.显示和隐藏带有动画的键盘的逻辑
func adjustInsetForKeyBoards(show: Bool, notification: NSNotification){
let userInfo = notification.userInfo ?? [:]
let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
UIView.animate(
withDuration: 1.0,
animations: {
let adjustment = (keyboardFrame.height * (show ? 1 : -1)) + 20
self.scrollView.contentInset.bottom += adjustment
self.scrollView.scrollIndicatorInsets.bottom += adjustment
},
completion: nil)
}
希望这对您有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.