You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:26:46