iOS UITextField输入文本时定位重置问题求助
解决iOS UITextField编辑时的键盘遮挡/屏幕上移问题
嘿,我完全懂这种被Auto Layout和键盘交互折腾得抓耳挠腮的感觉!你碰到的这个问题其实很常见,本质是键盘弹出时没有正确调整界面布局,要么让输入框被挡住,要么把整个内容顶得乱七八糟。下面给你分享几个原生的解决方案,亲测有效:
方案一:用UIScrollView包裹内容(最稳妥的原生方案)
这是处理键盘遮挡问题的标准做法,既能让输入框自动滚动到可视区域,又能避免整个屏幕乱移:
重构布局结构
- 把你原来的图片、UITextField全部放到一个
UIScrollView里面(如果有其他元素也一起放进去)。 - 给
UIScrollView设置和父视图(比如ViewController的view)四边完全对齐的约束,确保它占满整个屏幕。 - 在
UIScrollView内部添加一个contentView(UIView),给contentView设置这几个关键约束:- 顶部、底部、左侧、右侧和scrollView的对应边缘对齐
- contentView的宽度等于scrollView的宽度(防止横向滚动)
- contentView的高度可以根据内部元素的约束自动撑开,不用手动设置
- 把你原来的图片、UITextField全部放到一个
监听键盘通知,动态调整scrollView的内边距
在你的ViewController里添加以下代码:override func viewDidLoad() { super.viewDidLoad() // 注册键盘通知 NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil) } @objc private func keyboardWillShow(notification: NSNotification) { guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } // 获取键盘高度,注意要转换为当前视图的坐标系 let keyboardHeight = view.convert(keyboardFrame, from: nil).height // 设置scrollView的底部内边距,让内容能避开键盘 scrollView.contentInset.bottom = keyboardHeight scrollView.scrollIndicatorInsets.bottom = keyboardHeight // 让当前编辑的UITextField滚动到可视区域 if let activeTextField = UIResponder.currentFirstResponder as? UITextField { scrollView.scrollRectToVisible(activeTextField.frame, animated: true) } } @objc private func keyboardWillHide(notification: NSNotification) { // 键盘收起时恢复内边距 scrollView.contentInset.bottom = .zero scrollView.scrollIndicatorInsets.bottom = .zero } // 别忘了在deinit里移除通知 deinit { NotificationCenter.default.removeObserver(self) }这里用到的
currentFirstResponder是一个UIResponder的扩展,你可以自己实现:extension UIResponder { static weak var currentFirstResponder: UIResponder? { _currentFirstResponder = nil UIApplication.shared.sendAction(#selector(findFirstResponder(_:)), to: nil, from: nil, for: nil) return _currentFirstResponder } private static weak var _currentFirstResponder: UIResponder? @objc private func findFirstResponder(_ sender: Any) { UIResponder._currentFirstResponder = self } }
方案二:关闭系统自动调整(解决屏幕整体上移的问题)
如果你的界面已经用了UIScrollView,但还是出现整个屏幕上移、图片显示异常的情况,大概率是系统的自动调整内边距在搞鬼:
- iOS 11及以后:设置
scrollView.contentInsetAdjustmentBehavior = .never,这样系统就不会自动给scrollView添加额外的内边距,避免内容被顶上去。 - iOS 11以前:设置
automaticallyAdjustsScrollViewInsets = false(这个属性已经废弃,但旧版本还能用)
额外注意事项
- 确保你的UITextField的底部约束是和contentView的底部对齐(或者和其他元素有合理的间距),这样scrollView的contentSize才能正确计算,输入框才能被滚动到可视区域。
- 如果不想用scrollView,也可以单独给UITextField的底部约束添加IBOutlet,在键盘弹出时修改约束的constant值,把输入框往上推。但这种方法不如scrollView灵活,尤其是界面元素多的时候。
希望这些方法能帮你解决问题!我之前碰到几乎一样的场景,用第一个方案就完美搞定了😉
内容的提问来源于stack exchange,提问作者David




