簡體   English   中英

自定義 UIView 上的 IntrinsicContentSize 拉伸內容

[英]IntrinsicContentSize on a custom UIView streches the content

我想創建一個使用/提供 IntrinsicContentSize 的自定義UIView ,因為它的高度取決於其內容(就像高度取決於文本的 label 一樣)。

雖然我找到了很多關於如何使用現有視圖提供的 IntrinsicContentSize 的信息,但我發現了一些關於如何在自定義UIView上使用 IntrinsicContentSize 的信息:

@IBDesignable class MyIntrinsicView: UIView {
    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(UIColor.gray.cgColor)
        context?.fill(CGRect(x: 0, y: 0, width: frame.width, height: 25))
        
        height = 300
        invalidateIntrinsicContentSize()
    }
    
    
    @IBInspectable var height: CGFloat = 50
    override var intrinsicContentSize: CGSize {
        return CGSize(width: super.intrinsicContentSize.width, height: height)
    }
    
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        invalidateIntrinsicContentSize()
    }
}
  • 初始高點設置為50

  • draw方法繪制一個大小為25的灰色矩形

  • 高度更改為300並調用invalidateIntrinsicContentSize()

  • 在 InterfaceBuilder 中放置一個MyView實例沒有任何問題。 視圖不需要高度約束

但是,在 IB 中,使用了50的初始高度。 為什么? IB 繪制灰色矩形,因此調用draw方法。 那么為什么高度沒有改為300呢?

還有什么奇怪的:當設置背景顏色時,它也被繪制,也沒有調用super.draw(...) 這是故意的嗎?

我期望一個高度為300的視圖和一個高度為25的灰色矩形。 但是,在模擬器中運行項目時,結果是不同的:

  • 視圖的高度 = 300 - OK
  • 內容高度(= 灰色矩形)= 150(半視圖高度) -不正常

似乎內容從其原始高度25被拉伸以保持其與視圖的相對高度。 為什么是這樣?

在此處輸入圖像描述

嘗試從draw()內部更改視圖的高度可能是一個非常糟糕的主意。

首先,正如您所見,更改內在內容大小不會觸發重繪。 其次,如果是這樣,您的代碼將 go 進入無限遞歸循環。

看看對 class 的編輯:

@IBDesignable class MyIntrinsicView: UIView {
    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(UIColor.gray.cgColor)
        context?.fill(CGRect(x: 0, y: 0, width: frame.width, height: 25))

        // probably a really bad idea to do this inside draw()
        //height = 300
        //invalidateIntrinsicContentSize()
    }
    
    
    @IBInspectable var height: CGFloat = 50 {
        didSet {
            // call when height var is set
            invalidateIntrinsicContentSize()
            // we need to trigger draw()
            setNeedsDisplay()
        }
    }
    
    override var intrinsicContentSize: CGSize {
        return CGSize(width: super.intrinsicContentSize.width, height: height)
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        // not needed
        //invalidateIntrinsicContentSize()
    }
}

現在,當您通過IBDesignable屬性更改 IB 中的固有高度時,它將在您的 Storyboard 中正確更新。

下面是在運行時使用它的快速瀏覽。 每次點擊(任何地方)都會將height屬性增加 50 (直到我們超過 300,然后它將被重置為 50),然后使內在內容大小無效並強制調用draw()

class QuickTestVC: UIViewController {
    
    @IBOutlet var testView: MyIntrinsicView!
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        var h: CGFloat = testView.intrinsicContentSize.height
        h += 50
        if h > 300 {
            h = 50
        }
        testView.height = h
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM