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

IQKeyboardManager使用问题:如何让UINavigationBar固定在顶部

解决IQKeyboardManager导致UINavigationBar随键盘上移的问题

我之前做聊天应用时也碰到过一模一样的问题——IQKeyboardManager处理键盘交互确实省心,但默认配置会把整个导航控制器的视图都往上推,视觉效果特别怪异。给你几个亲测有效的解决办法,你可以根据项目情况选:

方法一:全局配置,让IQKeyboardManager忽略导航控制器

如果所有页面都不想让导航栏跟着键盘动,直接在AppDelegate或者项目初始化的地方加几行配置即可:

import IQKeyboardManagerSwift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 开启IQKeyboardManager核心功能
    IQKeyboardManager.shared.enable = true
    // 禁止它处理导航控制器的视图移动逻辑
    IQKeyboardManager.shared.disabledDistanceHandlingClasses = [UINavigationController.self]
    return true
}

设置后,IQKeyboardManager只会调整当前控制器的内容区域,不会触碰导航栏。

方法二:仅在聊天页面禁用全局调整,手动处理滚动视图

如果其他页面需要保留IQKeyboardManager的默认行为,只针对聊天页面修改的话,可以这么做:

首先在聊天ViewController的viewDidLoad里禁用当前控制器的自动调整,然后监听键盘通知手动调整UICollectionView的内边距:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 让IQKeyboardManager跳过当前控制器的全局视图调整
    IQKeyboardManager.shared.disabledViewControllerClasses = [ChatViewController.self]
    
    // 监听键盘弹出/收起通知
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    
    // iOS11+ 配置滚动视图的内边距调整行为,确保布局正确
    collectionView.contentInsetAdjustmentBehavior = .scrollableAxes
}

// 键盘弹出时调整集合视图内边距,让内容不被键盘遮挡
@objc private func keyboardWillShow(_ notification: Notification) {
    guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
    let keyboardHeight = keyboardFrame.height
    
    let inset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
    collectionView.contentInset = inset
    collectionView.scrollIndicatorInsets = inset
    
    // 可选:自动滚动到最新消息,提升聊天体验
    if let lastIndexPath = collectionView.indexPathsForVisibleItems.last {
        collectionView.scrollToItem(at: lastIndexPath, at: .bottom, animated: true)
    }
}

// 键盘收起时恢复内边距
@objc private func keyboardWillHide(_ notification: Notification) {
    collectionView.contentInset = .zero
    collectionView.scrollIndicatorInsets = .zero
}

记得在deinit里移除通知观察者,避免内存泄漏:

deinit {
    NotificationCenter.default.removeObserver(self)
}

方法三:设置导航栏为不透明(最简单的方案)

如果你的导航栏不需要半透明效果,这个方法最省心。只要在聊天ViewController里设置导航栏不透明,IQKeyboardManager就会自动识别,只调整下方的内容视图:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 关闭导航栏半透明属性
    navigationController?.navigationBar.isTranslucent = false
    // 设置导航栏背景色(根据你的设计需求修改)
    navigationController?.navigationBar.barTintColor = .systemBackground
    // 确保视图布局从导航栏下方开始(用AutoLayout约束到safeAreaTop即可)
}

这个方法不需要修改IQKeyboardManager的任何配置,只要导航栏不透明,它就不会把导航栏算进可移动的区域里,我当时就是用这个方法快速解决的问题!

内容的提问来源于stack exchange,提问作者FS.O6

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:21:24