iOS键盘遮挡TextField,调整View位置出现黑块问题排查
解决键盘遮挡TextField及视图回滚黑块问题
嘿,我之前也踩过直接修改self.view.frame.origin.y的坑!这种方式确实偶尔能凑效,但真机上很容易因为系统布局时机、Auto Layout约束冲突等问题,导致键盘隐藏后视图没正确复位,出现底部黑块。改用CGAffineTransform做视图平移是更稳妥的方案,给你分享下具体实现和注意事项:
一、用CGAffineTransform实现视图平移
1. 注册键盘通知
在viewDidLoad里添加键盘显示/隐藏的通知监听:
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) }
2. 实现键盘响应方法
通过CGAffineTransform来平移视图,键盘隐藏时恢复初始状态:
@objc private func keyboardWillShow(_ notification: Notification) { guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } // 获取键盘高度,可根据实际需求调整平移距离(比如加上TextField到底部的间距) let keyboardHeight = keyboardFrame.height // 向上平移视图,y轴取负值 self.view.transform = CGAffineTransform(translationX: 0, y: -keyboardHeight) } @objc private func keyboardWillHide(_ notification: Notification) { // 恢复视图到初始位置 self.view.transform = .identity }
3. 移除通知避免内存泄漏
在视图销毁时移除通知监听:
deinit { NotificationCenter.default.removeObserver(self) }
二、额外优化方案(针对ScrollView场景)
如果你的TextField放在UIScrollView(或其子类如UITableView、UICollectionView)里,更推荐调整滚动视图的内边距,这样用户还能滚动查看其他内容:
@objc private func keyboardWillShow(_ notification: Notification) { guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } let inset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height, right: 0) scrollView.contentInset = inset scrollView.scrollIndicatorInsets = inset } @objc private func keyboardWillHide(_ notification: Notification) { scrollView.contentInset = .zero scrollView.scrollIndicatorInsets = .zero }
三、为什么修改frame会出黑块?
直接修改self.view.frame.origin.y容易和Auto Layout冲突:当系统触发布局更新时,约束会强制把视图的frame复位,或者导致视图的bounds没有正确适配屏幕,从而出现底部黑块。而CGAffineTransform是对视图做视觉变换,不会改变视图的原始frame和bounds,恢复时用.identity就能完全回到初始状态,稳定性更高。
内容的提问来源于stack exchange,提问作者PrepareFor
相关产品推荐
相关产品推荐

