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

通过UIButton控制UITextView展开收起 而非随内容自动适配

问题根因
  1. sizeThatFits(_:) 仅返回计算后的最优尺寸,不会主动修改视图的frame,原有代码中该行逻辑无效
  2. 反复切换translatesAutoresizingMaskIntoConstraints会和IB预设约束冲突,导致尺寸计算异常,不需要做此操作
  3. sizeToFit()会同时调整宽高的本质原因是你没有给textView固定横向约束,系统计算最优尺寸时会同时修改宽高数值
实现方案

步骤1:配置IB约束

在Interface Builder中给你的UITextView添加如下约束:

  • 相对于父UIView的leading、trailing、top、bottom约束固定,确保宽度不会随内容变化
  • 添加高度约束,默认值设为70,并将该约束拖线关联到控制器代码,属性示例:
@IBOutlet weak var textViewHeightConstraint: NSLayoutConstraint!
  • 初始状态下myTextView.isScrollEnabled = true,符合收起时可滚动查看内容的表现

步骤2:替换状态监听逻辑

替换你原有textViewIsExpanded的didSet实现:

var textViewIsExpanded: Bool = false {
    didSet {
        expandTextViewButton.isSelected = textViewIsExpanded
        // 基于textView当前固定宽度计算实际内容高度
        let actualHeight = myTextView.sizeThatFits(CGSize(width: myTextView.bounds.width, height: .greatestFiniteMagnitude)).height
        
        if textViewIsExpanded {
            // 内容高度不足时不触发展开
            guard actualHeight > 70 else { return }
            myTextView.isScrollEnabled = false
            textViewHeightConstraint.constant = actualHeight
        } else {
            myTextView.isScrollEnabled = true
            textViewHeightConstraint.constant = 70
        }
        // 触发布局更新,带动画过渡效果,同时自动更新UIScrollView的contentSize
        UIView.animate(withDuration: 0.25) {
            self.view.layoutIfNeeded()
        }
    }
}

按钮点击的逻辑不需要修改,原有实现可正常复用。

注意事项
  • 全程不要修改translatesAutoresizingMaskIntoConstraints的取值,基于约束修改高度的方式兼容性更强,不会和其他布局规则冲突
  • 不需要手动计算scrollView宽度来适配textView宽度,已固定的横向约束会保证textView宽度符合预期,计算高度时不会出现宽度偏差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 14:15:03