使用Swift移动视图以配合键盘:优化与性能
\n\n每位iOS开发者至少都遇到过这样的情况:键盘粗暴地遮挡了UITextField或UITextView。用户点击输入框,键盘弹出,但界面却无动于衷。结果就是——用户烦躁、输入错误,甚至卸载应用。在Swift中解决这个问题,不仅仅是“move view with keyboard”,更是一门关于性能和用户体验的科学。
在本文中,我们将详细讲解如何正确实现使用Swift移动视图以配合键盘,优化动画并避免常见错误。您将获得可直接插入项目的现成代码,并理解为什么某些方法会拖慢UI,而另一些则能完美运行。
\n\n为什么标准解决方案常常效果不佳?
\n\n在Stack Overflow上,问题“使用Swift移动视图以配合键盘”获得了数千次浏览。这并非偶然。许多新手直接复制2015年的第一个解决方案,该方案使用UIKeyboardWillShowNotification并硬性更改UIView的frame。结果就是:动画卡顿、内存泄漏以及在不同iPhone型号上的bug。
旧方法的主要问题:
\n- \n
- 直接修改
frame而不考虑safe area; \n - 忽略键盘动画的持续时间和曲线; \n
- 缺乏对屏幕旋转和多任务处理的支持; \n
- 健忘:通知未移除,对象未清理。 \n
现代Swift (5.0+) 和 UIKit 可以让一切变得优雅而高效。让我们来分析最佳模式。
\n\n准备工作:我们需要什么
\n\n为了实现使用Swift移动视图以配合键盘,我们将使用:
\n- \n
NotificationCenter来监听键盘事件; \n UIView.animate配合通知中的参数; \n UIScrollView作为基础容器(但也可以不用); \n - 正确的内存管理(weak self, removeObserver)。 \n
所有代码将在UIViewController中编写。如果您使用SwiftUI——原理相同,但API不同(文章末尾会提到)。
步骤1:注册键盘通知
\n\n首先,需要订阅两个关键通知:UIResponder.keyboardWillShowNotification 和 UIResponder.keyboardWillHideNotification。正是它们提供了键盘的尺寸、持续时间和动画曲线。
override func viewDidLoad() {\n super.viewDidLoad()\n \n NotificationCenter.default.addObserver(\n self,\n selector: #selector(keyboardWillShow),\n name: UIResponder.keyboardWillShowNotification,\n object: nil\n )\n \n NotificationCenter.default.addObserver(\n self,\n selector: #selector(keyboardWillHide),\n name: UIResponder.keyboardWillHideNotification,\n object: nil\n )\n}\n\n\n请注意:object: nil 表示我们监听来自任何键盘的通知。这在大多数情况下是正确的。
步骤2:keyboardWillShow 处理程序
\n\n在此方法中,我们从通知中提取键盘尺寸和动画持续时间。然后将视图向上移动键盘的高度。
\n\n@objc private func keyboardWillShow(_ notification: Notification) {\n guard let userInfo = notification.userInfo,\n let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,\n let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,\n let curve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {\n return\n }\n \n let keyboardHeight = keyboardFrame.height\n let animation