计算并随键盘显隐移动UITextField及其父UIView的技术问题
我懂你的困扰——IQKeyboardManager有时候确实搞不定一些特殊布局场景,那咱们就自己动手实现键盘适配逻辑,核心就是监听键盘的弹出/收起事件,计算需要移动的距离,再给视图加个同步动画就行,我给你一步步拆解:
手动实现键盘适配的步骤
1. 准备工作:注册通知+保存原始位置
首先得监听键盘的弹出和收起事件,同时提前保存父视图的原始位置,方便后续恢复。
代码示例(Swift)
import UIKit class YourViewController: UIViewController, UITextFieldDelegate { // 假设你的文本框和父视图 private let inputTextField = UITextField() private let contentContainerView = UIView() // 保存父视图的原始位置(如果用Frame布局) private var originalContainerFrame: CGRect = .zero // 如果用Auto Layout,就保存约束的原始值 @IBOutlet weak var containerTopConstraint: NSLayoutConstraint! private var originalTopConstant: CGFloat = 0 override func viewDidLoad() { super.viewDidLoad() // 初始化并布局你的视图(这里省略布局代码,按你自己的方式来) setupViews() // 注册键盘通知 NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) // 保存原始位置/约束值 originalContainerFrame = contentContainerView.frame originalTopConstant = containerTopConstraint.constant } // 页面销毁时移除通知,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) } }
2. 处理键盘弹出:计算偏移并移动视图
当键盘弹出时,我们需要判断文本框是否被遮挡,算出需要上移的距离,然后用和键盘同步的动画参数移动父视图。
@objc private func keyboardWillShow(_ notification: Notification) { // 获取键盘的高度和动画参数 guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect, let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else { return } let keyboardHeight = keyboardFrame.height // 计算文本框相对于窗口的底部位置 let textFieldBottom = inputTextField.convert(inputTextField.bounds, to: nil).maxY // 获取当前页面的可视区域底部(考虑安全区域) let visibleViewBottom = view.safeAreaLayoutGuide.layoutFrame.maxY // 计算需要上移的距离:如果文本框底部超出了可视区域(减去键盘高度),就需要移动 let offset = max(0, textFieldBottom - (visibleViewBottom - keyboardHeight)) // 执行动画移动视图 UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: curve)) { // 方式1:Frame布局的情况 self.contentContainerView.frame = CGRect( x: self.originalContainerFrame.origin.x, y: self.originalContainerFrame.origin.y - offset, width: self.originalContainerFrame.width, height: self.originalContainerFrame.height ) // 方式2:Auto Layout的情况(注释掉上面的Frame代码,用这个) // self.containerTopConstraint.constant = self.originalTopConstant - offset // self.view.layoutIfNeeded() } }
3. 处理键盘收起:恢复视图到原始位置
键盘收起时,把父视图移回一开始保存的位置,同样用同步的动画保证过渡自然。
@objc private func keyboardWillHide(_ notification: Notification) { guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else { return } UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: curve)) { // 方式1:Frame布局恢复 self.contentContainerView.frame = self.originalContainerFrame // 方式2:Auto Layout恢复(注释掉上面的Frame代码,用这个) // self.containerTopConstraint.constant = self.originalTopConstant // self.view.layoutIfNeeded() } }
额外注意事项
- 如果有多个文本框,记得实现
UITextFieldDelegate的textFieldDidBeginEditing(_:)方法,记录当前活跃的文本框,计算偏移量时用这个文本框的位置 - 测试时要覆盖横屏、不同屏幕尺寸、带安全区域的设备(比如刘海屏)
- 可以给文本框添加点击空白区域收起键盘的逻辑,提升用户体验
内容的提问来源于stack exchange,提问作者Ibrahim Azhar Armar
相关产品推荐
相关产品推荐

