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

Swift更新Main.storyboard约束时无法访问textView底部约束问题

问题根本原因

你要找的底部约束本身就不存在于self.textView.constraints数组中:

  • iOS布局系统中,视图的constraints数组仅存储两类约束:一类是作用于该视图自身的内部约束(比如固定宽高约束),另一类是该视图和它的直接子视图之间的约束。
  • 你在Storyboard中设置的textView底部约束,属于textView和它的父视图之间的跨视图约束,这类约束默认会被添加到两个视图的最近公共父视图上,也就是textView的父视图的constraints数组里,所以你遍历textView的约束数组自然匹配不到目标。
  • 补充说明:正常加载完成的textView的constraints不会为nil,只会是空数组,如果你确认拿到的是nil,需要先检查textView的IBOutlet关联是否正常,有没有提前在视图未加载完成的时候访问了textView属性。

代码修复方案

方案1:直接关联约束IBOutlet(推荐)

不需要遍历查找,直接在Storyboard中把标识符为bottomTextViewConstraint的约束拖线关联到当前控制器的属性,拿到引用后直接修改即可,代码示例:

// 控制器中声明约束属性
@IBOutlet weak var bottomTextViewConstraint: NSLayoutConstraint!

@objc func keyboardWillShow(notification: NSNotification) {
    guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
        return
    }
    bottomTextViewConstraint.constant = keyboardSize.height
    // 修改常量后触发父视图布局生效,不要调用textView.updateConstraints()
    view.layoutIfNeeded()
}

方案2:遍历父视图约束查找

如果你不想拖线关联,修改遍历逻辑,从textView的父视图的约束数组中匹配标识符即可:

@objc func keyboardWillShow(notification: NSNotification) {
    guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
          let superview = textView.superview else {
        return
    }
    for constraint in superview.constraints {
        if constraint.identifier == "bottomTextViewConstraint" {
            constraint.constant = keyboardSize.height
            break
        }
    }
    view.layoutIfNeeded()
}

另外注意你原代码中的错误:修改约束constant后调用textView.updateConstraints()不会触发布局生效,需要调用当前控制器根视图的layoutIfNeeded()方法才能让约束变更生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:06:08