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

自定义UIView使用IntrinsicContentSize出现内容拉伸及IB高度异常问题

问题1解答

  • 为什么IB里高度没有更新为300:
    Interface Builder的设计时渲染流程是单轮闭环的,首次计算自定义视图的固有尺寸时,height属性还保留初始值50,后续你在draw(_:)方法中修改height并调用invalidateIntrinsicContentSize(),不会触发IB侧的二次布局重算流程,因此IB中始终以初始的50作为视图高度。
  • 未调用super.draw(_:)背景色仍正常渲染是预期行为:
    UIView的背景色渲染是系统在调用draw(_:)方法之前独立完成的逻辑,和你是否调用父类的draw方法无关,draw(_:)仅负责处理自定义的绘制内容,不会影响系统层面的基础视图属性渲染。

问题2解答

出现灰色矩形被拉伸到150高度的核心原因是UIView默认的contentMode属性为.scaleToFill:

  1. 首次触发draw(_:)时,视图的高度为初始的50,你绘制了高度为25的灰色矩形(占视图高度的1/2),系统会将本次绘制的内容缓存为位图
  2. 你在draw中修改height为300并触发固有尺寸更新后,视图的bounds高度变为300,默认的.scaleToFill模式会直接将之前缓存的位图拉伸适配新的视图尺寸,因此原本25高的灰色矩形会等比拉伸为150高,正好是300的1/2。

正确实现方案

要实现高度自适应的自定义视图,需要调整实现逻辑,不要在draw(_:)方法中修改视图布局相关属性:

@IBDesignable class MyIntrinsicView: UIView {
    // 触发高度更新的业务属性,可根据实际需求替换为文本、内边距等
    @IBInspectable var contentHeight: CGFloat = 50 {
        didSet {
            invalidateIntrinsicContentSize()
            // 内容变化需要重绘时主动调用
            setNeedsDisplay()
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        // 尺寸变化时自动重绘,避免缓存拉伸
        contentMode = .redraw
    }
    
    override var intrinsicContentSize: CGSize {
        // 宽度不做固有约束,跟随父视图/横向约束
        return CGSize(width: UIView.noIntrinsicMetric, height: contentHeight)
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.setFillColor(UIColor.gray.cgColor)
        // 这里始终绘制顶部25高的灰色条,不会被拉伸
        context.fill(CGRect(x: 0, y: 0, width: bounds.width, height: 25))
    }
    
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        invalidateIntrinsicContentSize()
    }
}

如果需要动态修改高度,只需要修改contentHeight属性即可自动触发尺寸更新和重绘,IB和运行时表现会保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 13:15:05