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

iOS中键盘收起后如何让UIButton回到原位置并解决约束崩溃问题

问题原因

你遇到的崩溃是confirmButtonBottomConstrains隐式解包失败导致的,根本原因如下:

  • 当你执行othersTextField.inputAccessoryView = confirmButton时,系统会自动将confirmButton从它原本所在的父视图中移除,挂载到键盘的视图层级下
  • 原本绑定在confirmButton和父视图之间的底部约束confirmButtonBottomConstrains,因为约束的其中一端视图已经脱离父视图,会被系统自动销毁,你存储的约束变量就会变成nil
  • 键盘收起时你直接访问这个已经变成nil的隐式可选约束,就触发了强制解包崩溃
修复方案

步骤1:调整键盘收起逻辑

先将按钮重新加回父视图,再操作约束,如果约束已经销毁就重新创建:

@objc func keyboardWillHide(_ notification: Notification) {
    othersTextField.inputAccessoryView = nil
    // 先把按钮加回原父视图,如果按钮原父视图不是self.view请自行替换
    self.view.addSubview(confirmButton)
    confirmButton.layer.cornerRadius = 20.0 // 恢复按钮原始圆角
    
    // 先判空,如果约束已经销毁就重新创建
    if confirmButtonBottomConstrains == nil {
        // 移除按钮旧的位置约束避免冲突
        confirmButton.constraints.forEach { constraint in
            if [.bottom, .leading, .trailing, .height].contains(constraint.firstAttribute) {
                confirmButton.removeConstraint(constraint)
            }
        }
        confirmButton.translatesAutoresizingMaskIntoConstraints = false
        // 补充按钮的水平、高度约束,数值和你原始布局保持一致即可
        confirmButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
        confirmButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
        confirmButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
        // 重新创建底部约束并赋值
        confirmButtonBottomConstrains = confirmButton.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -57)
        confirmButtonBottomConstrains.isActive = true
    } else {
        confirmButtonBottomConstrains.constant = 57
    }

    let userInfo = notification.userInfo
    let animationDuration = userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
    UIView.animate(withDuration: animationDuration) {
        self.view.layoutIfNeeded()
    }
}

步骤2:优化属性声明

把confirmButtonBottomConstrains的声明从隐式解包类型NSLayoutConstraint!改成普通可选类型NSLayoutConstraint?,避免意外解包崩溃。

可选优化方案

如果按钮样式固定,你也可以直接创建两个相同的按钮实例:一个固定在屏幕底部,一个专门作为inputAccessoryView使用,两个按钮绑定同一个点击事件即可,不需要来回移动视图,逻辑更简单不容易出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:57:03