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

Swift 3.0自定义NavigationBar场景下TextView键盘适配问题求助

嘿,这个问题我之前做项目时也踩过坑!IQKeyboardManager确实能省不少事,但碰到自定义导航栏时,它默认的导航栏自动调整就会搞出小麻烦。给你几个实用的解决方案,按优先级试试:

解决方案

方案一:临时禁用当前控制器的导航栏自动调整(最推荐)

IQKeyboardManager有个全局属性shouldAdjustNavigationBar,默认是开启的,会自动调整导航栏位置。我们可以在当前控制器的生命周期里临时关闭它,离开页面再恢复,这样不会影响其他页面的逻辑:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // 进入页面时关闭导航栏自动调整
    IQKeyboardManager.shared.shouldAdjustNavigationBar = false
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    // 离开页面时恢复全局设置,避免影响其他控制器
    IQKeyboardManager.shared.shouldAdjustNavigationBar = true
}

这样既保留了IQKeyboardManager帮你把TextView顶到键盘上方的功能,又能让自定义导航栏稳稳固定在顶部。

方案二:给自定义导航栏添加固定顶部的AutoLayout约束

如果你的自定义导航栏是自己添加到view上的(不是系统UINavigationController的导航栏),那确保给它设置了严格的顶部约束,不让它跟着其他视图偏移:

// 假设你的自定义导航栏实例是customNavBar
customNavBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    customNavBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
    customNavBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    customNavBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    customNavBar.heightAnchor.constraint(equalToConstant: 64) // 根据你的需求调整高度
])

有了这些约束,即使IQKeyboardManager调整了主视图的frame,自定义导航栏也会因为固定在安全区顶部而保持不动。

方案三:手动监听键盘通知(完全可控)

如果前面两个方案都不适用,那可以放弃IQKeyboardManager的自动调整逻辑,手动监听键盘弹出/收起事件来调整TextView的位置,这样完全掌握控制权:

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: Notification) {
    guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
    let keyboardHeight = keyboardFrame.height
    
    // 假设你给TextView设置了底部约束textViewBottomConstraint
    textViewBottomConstraint.constant = -keyboardHeight
    
    // 执行动画,和键盘弹出动画保持一致
    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
}

@objc private func keyboardWillHide(_ notification: Notification) {
    // 恢复TextView的底部约束
    textViewBottomConstraint.constant = 0
    
    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
}

// 记得在控制器销毁时移除通知
deinit {
    NotificationCenter.default.removeObserver(self)
}

这种方式虽然代码多一点,但完全不会影响导航栏的位置,因为你只调整TextView的约束,导航栏的固定约束不受任何影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:00:52