当iOS设备旋转且键盘打开时,NotificationCenter会发送UIKeyboardWillChangeFrame通知。我正在尝试在这一点上启动自定义动画。它不起作用。
我正在尝试启动布局约束动画,但我无法使用任何自定义动画持续时间,因为它以某种方式被系统覆盖。我将始终获得与键盘向上/向下移动动画相匹配的恒定持续时间。在这种情况下,我如何使用自己的动画持续时间。
下面是我所需行为的代码示例:
@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-overrideinheritedduration -
你不应该碰
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. 注册键盘 在视图中隐藏和显示通知DidLoad()
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)
}
希望这对您有用。