How to set a custom view's intrinsic content s

2019-01-21 07:49发布

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.

2条回答
虎瘦雄心在
2楼-- · 2019-01-21 08:28

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

查看更多
Ridiculous、
3楼-- · 2019-01-21 08:32

Based on the excellent answer above,

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
    }
}

enter image description here

which you can set as an inspectable

enter image description here

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 special case of a stack view:

  • you only have to worry about one only 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.

查看更多
登录 后发表回答