简体   繁体   中英

How to set a custom view's intrinsic content size in Swift?

Background

I am making a vertical label to use with traditional Mongolian script. Before I was just rotating a UILabel but there were some performance issues and other complications with this. Now I am working on making a label from scratch. However, I need the vertical label to tell auto layout when its height adjusts (based on string length).

What I have read

I read the Intrinsic Content Size and Views with Intrinsic Content Size documentation. These were more about how to use it, though, and not how to define it in a custom view.

Searching for "ios intrinsic content size for a custom view" only gives me

in Stack Overflow. This particular question didn't even need intrinsic content size because their view was just an assembly of standard views.

What I am trying

What I am trying is my answer below. I am adding this Q&A pair so that it won't take other people as long to find the answer as it took me with the search keywords that I used.

Setting the intrinsic content size of a custom view lets auto layout know how big that view would like to be. In order to set it, you need to override intrinsicContentSize .

override var intrinsicContentSize: CGSize {
   return CGSize(width: x, height: y)
}

Then call

invalidateIntrinsicContentSize()

Whenever your custom view's intrinsic content size changes and the frame should be updated.

Notes

Example of a "view with intrinsic height" ...

@IBDesignable class HView: UIView {

    @IBInspectable var height: CGFloat = 100.0

    override var intrinsicContentSize: CGSize {
        return CGSize(width: 99, height: height)
        // if using in, say, a vertical stack view, the width is ignored
    }

    override func prepareForInterfaceBuilder() {
         invalidateIntrinsicContentSize()
    }
}

在此处输入图片说明

which you can set as an inspectable

在此处输入图片说明

Since it has an intrinsic height, it can (for example) be immediately inserted in a stack view in code:

stack?.insertArrangedSubview(HView(), at: 3)

In contrast, if it was a normal view with no intrinsic height, you'd have to add a height anchor or it would crash:

let v:UIView = HView()
v.heightAnchor.constraint(equalToConstant: 100).isActive = true
stack?.insertArrangedSubview(v, at: 3)

Note that in ...

the important special case of a stack view:

  • you set only ONE anchor (for vertical stack view, the height; for horizontal the width)

so, setting the intrinsic height works perfectly, since:

  • the intrinsic height indeed means that the height anchor specifically will be set automatically if needed.

Remembering that in all normal cases of a subview, many other anchors are needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM