ios - 调整约束高度后,Swift 约束无法移回屏幕底部
问题描述
我有一个使用自动布局的按钮位于屏幕底部。我正在尝试使按钮调整位置始终位于键盘上方。到目前为止,我已经能够让按钮向上移动,但我无法让按钮的位置重置。
我完全以编程方式做所有事情,我根本不使用故事板。没有插座的解决方案将不胜感激。
我的viewDidLoad
功能(仅显示与按钮移动相关的逻辑)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardMovedUp(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardMovedDown(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
keyboardMovedUp
功能_
@objc
func keyboardMovedUp(notification: Notification) {
if let userInfo = notification.userInfo {
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let viewEndFrame = view.convert(endFrame!, from: view.window)
let endFrameY = endFrame?.origin.y ?? 0
let animationRate = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue
let animationCurveRawNSM = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSM?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve: UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
self.moveUp = self.continueButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -viewEndFrame.origin.y)
self.moveUp?.isActive = true
UIView.animate(withDuration: animationRate!, delay: TimeInterval(0), options: animationCurve, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
}
和我的keyboardMovedDown
功能
@objc
func keyboardMovedDown(notification: Notification) {
if let userInfo = notification.userInfo {
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
self.moveUp?.isActive = false
self.moveDown = self.continueButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20)
self.moveDown?.isActive = true
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
}
使用此代码,当显示键盘时,按钮将向上移动,但在重置键盘后按钮不会移动位置。
我可以通过修改origin.y
按钮的参数来使代码正常工作,但我听说这会导致自动布局的兼容性问题。
编辑:@IchBinStudenten 这就是我当前的代码在您的更改后的样子
func viewDidLoad() {
self.moveUp = self.continueButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20)
self.moveUp?.isActive = true
}
@objc
func keyboardMoved(notification: Notification) {
if let userInfo = notification.userInfo {
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let viewEndFrame = view.convert(endFrame!, from: view.window)
let endFrameY = endFrame?.origin.y ?? 0
let animationRate = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue
let animationCurveRawNSM = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSM?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve: UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
self.moveUp?.constant = -viewEndFrame.height - 20
UIView.animate(withDuration: animationRate!, delay: TimeInterval(0), options: animationCurve, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
}
@objc
func keyboardMovedDown(notification: Notification) {
if let userInfo = notification.userInfo {
self.moveUp?.constant = 0
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
}
解决方案
使用 1 个约束足以实现您想要的。无论如何,您都在使用一种约束。self.moveUp
当键盘向上移动时设置为活动,并更改其值
self.moveUp?.constant = -20.0
当键盘向下移动时。为了保持代码更简洁,只需self.continueButton.bottomAnchor.constraint(equalTo:self.view.bottomAnchor)
通过在类中创建一些变量来保留对的引用,以便您只能修改其常量属性。例如:
let keyboardConstraint: NSLayoutConstraint
override func viewDidLoad() {
self.keyboardConstraint = self.continueButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
self.keyboardConstraint.isActive = true
}
@objc
func keyboardMovedUp(notification: Notification) {
/// ...your code
self.keyboardConstraint.constant = -viewEndFrame.origin.y
UIView.animate(withDuration: animationRate!, delay: TimeInterval(0), options: animationCurve, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
}
@objc
func keyboardMovedDown(notification: Notification) {
if let userInfo = notification.userInfo {
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
self.keyboardConstraint.constant = -20.0
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
}
另一种选择是通过 CocoaPods 安装IQKeyboardManager,它会为您管理一切。
让我知道这是否能解决您的问题。
推荐阅读
- ruby - “vanilla” Ruby dotenv 是否会拾取 .env 以外的任何文件?
- html - 我是否总是需要在引导程序中使用容器/容器流体?
- sql-server - 可以使用 SSMS 和 VS 连接和访问 SQL Server 数据库,但在报告代码中登录失败
- asp.net-mvc - 为什么我的 post dall 没有在 MVC 和 Angular 7 中获取数据
- javascript - Semanticui 侧边栏图标悬停不显示菜单项
- mongodb - MapReduce 函数返回两个输出。MongoDB
- r - 如何扩展给定的数字范围以包括用破折号分隔的所有数字
- uart - LoRa UART 还是 SPI?
- apache-spark - Python 工作者无法在 Pyspark 或 spark 版本 2.3.1 中重新连接
- facebook-graph-api - 有什么方法可以从 Facebook 获取公共事件信息?