Move View with Keyboard Swift:优化与性能

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

使用Swift移动视图以配合键盘:优化与性能

\n\n

每位iOS开发者至少都遇到过这样的情况:键盘粗暴地遮挡了UITextField或UITextView。用户点击输入框,键盘弹出,但界面却无动于衷。结果就是——用户烦躁、输入错误,甚至卸载应用。在Swift中解决这个问题,不仅仅是“move view with keyboard”,更是一门关于性能和用户体验的科学。

\n\n

在本文中,我们将详细讲解如何正确实现使用Swift移动视图以配合键盘,优化动画并避免常见错误。您将获得可直接插入项目的现成代码,并理解为什么某些方法会拖慢UI,而另一些则能完美运行。

\n\n

为什么标准解决方案常常效果不佳?

\n\n

在Stack Overflow上,问题“使用Swift移动视图以配合键盘”获得了数千次浏览。这并非偶然。许多新手直接复制2015年的第一个解决方案,该方案使用UIKeyboardWillShowNotification并硬性更改UIView的frame。结果就是:动画卡顿、内存泄漏以及在不同iPhone型号上的bug。

\n\n

旧方法的主要问题:

\n
    \n
  • 直接修改frame而不考虑safe area;
  • \n
  • 忽略键盘动画的持续时间和曲线;
  • \n
  • 缺乏对屏幕旋转和多任务处理的支持;
  • \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
\n\n

所有代码将在UIViewController中编写。如果您使用SwiftUI——原理相同,但API不同(文章末尾会提到)。

\n\n

步骤1:注册键盘通知

\n\n

首先,需要订阅两个关键通知:UIResponder.keyboardWillShowNotification 和 UIResponder.keyboardWillHideNotification。正是它们提供了键盘的尺寸、持续时间和动画曲线。

\n\n
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 表示我们监听来自任何键盘的通知。这在大多数情况下是正确的。

\n\n

步骤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                

博客

书籍推荐