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

CollectionView内容无法随键盘上移问题排查求助

解决CollectionView在键盘弹出时Cell无法上移的问题

最近我碰到个头疼的问题:想让CollectionView的Cell在键盘弹出时自动移到键盘上方,我本来的思路是监听键盘通知,获取键盘尺寸后修改CollectionView的contentInset,但奇怪的是——用模拟器快捷键⌘K弹出键盘时功能正常,可点击TextField唤起键盘(不管是模拟器还是真机),Cell就是不动,不过控制台能打印出"will show?",说明键盘通知是正常触发的。

我一开始写的代码是这样的:

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.view.addSubview(collectionV) 
    collectionV.dataSource = self 
    collectionV.delegate = self 
    collectionV.alwaysBounceVertical = true 
    collectionV.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 45, right: 0) 
    collectionV.backgroundColor = UIColor.white 
    collectionV.keyboardDismissMode = .interactive 
    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow), name: .UIKeyboardWillShow, object: nil) 
    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide), name: .UIKeyboardWillHide, object: nil) 
}

@objc func handleKeyboardWillShow(notification: Notification) { 
    print("will show?") 
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { 
        let userInfo = notification.userInfo! 
        let animationDuration: TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue 
        ContainerViewBottomAnchor?.constant = -keyboardSize.height 
        collectionV.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: keyboardSize.height+8, right: 0) 
        UIView.animate(withDuration: animationDuration) { 
            self.view.layoutIfNeeded() 
        } 
    } 
}

@objc func handleKeyboardWillHide(notification: Notification) { 
    print("will hide?") 
    let userInfo = notification.userInfo! 
    let animationDuration: TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue 
    ContainerViewBottomAnchor?.constant = 0 
    self.collectionV.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 45, right: 0) 
    UIView.animate(withDuration: animationDuration) { 
        self.view.layoutIfNeeded() 
    } 
}

后来经过排查,发现问题出在获取键盘尺寸的key上!把获取键盘尺寸的代码从:

let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue

修改为:

let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue

之后,不管是点击TextField还是用快捷键,真机还是模拟器,Cell都能正常上移到键盘上方了,感谢@MichaelVorontsov的提示。

这里解释下原因:UIKeyboardFrameBeginUserInfoKey获取的是键盘开始弹出瞬间的frame,这时候键盘还在动画过程中,尺寸可能不是最终的正确值;而UIKeyboardFrameEndUserInfoKey获取的是键盘动画完成后的最终frame,这个尺寸才是我们用来调整CollectionView inset的准确值,所以替换后问题就解决了。

内容的提问来源于stack exchange,提问作者Salah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:59:55