自定义 UIView 上的 IntrinsicContentSize 拉伸内容 [英] IntrinsicContentSize on a custom UIView streches the content
问题描述
我想创建一个使用/提供 IntrinsicContentSize 的自定义 UIView
,因为它的高度取决于它的内容(就像一个高度取决于文本的标签).
I would like to create a custom UIView
which uses/offers a IntrinsicContentSize, since its height depends on its content (just like a label where the height depends on the text).
虽然我找到了很多关于如何使用现有视图提供的 IntrinsicContentSize 的信息,但我只发现了一些关于如何在自定义 UIView
上使用 IntrinsicContentSize 的信息:
While I found a lot of information on how to work with IntrinsicContentSize offered by existing Views, I found just a few bits on how to use IntrinsicContentSize on a custom UIView
:
@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
The
draw
methods draws a gray rect with a size25
height 改为
300
并调用invalidateIntrinsicContentSize()
height is changed to
300
andinvalidateIntrinsicContentSize()
is called在 InterfaceBuilder 中放置
MyView
实例没有任何问题.视图不需要高度约束Placing a
MyView
instance in InterfaceBuilder works without any problem. The view does not need a height constraint然而,在 IB 中使用了
50
的初始高度.为什么? IB绘制灰色矩形,从而调用draw
方法.那为什么高度没有改成300呢?However, in IB the initial height of
50
is used. Why? IB draws the gray rect, thus thedraw
method is called. So why is the height not changed to 300?还有什么奇怪的:当设置背景颜色时,它也会被绘制,而且
super.draw(...)
也没有被调用.这是故意的吗?What is also strange: When setting a background color it is drawn as well, also
super.draw(...)
is not called. Is this intended?我希望视图高度为
300
,顶部有一个灰色矩形,高度为25
.但是,在模拟器中运行项目时,结果是不同的:I would expect a view with height of
300
and a gray rect at the top with a height of25
. However, when running the project in simulator the result is different:- 视图高度 =
300
- OK - 内容的高度(= 灰色矩形)= 150(半视图高度)-不行
似乎内容是从其原始高度
25
拉伸以保持其相对于视图的高度.这是为什么?It seems that the content was stretched from its original height of
25
to keep its relative height to the view. Why is this?推荐答案
尝试从
draw()
内部更改视图的高度可能是一个非常糟糕的主意.Trying to change the view's height from inside
draw()
is probably a really bad idea.首先,如您所见,更改内在内容大小不会触发重绘.其次,如果是这样,您的代码将进入无限递归循环.
First, as you've seen, changing the intrinsic content size does not trigger a redraw. Second, if it did, your code would go into an infinite recursion loop.
看看这个对你的班级的
@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 中正确更新.Now, when you change the intrinsic height in IB via the
IBDesignable
property, it will update in your Storyboard properly.这是在运行时使用它的快速浏览.每次点击(任何地方)都会将
height
属性增加 50(直到我们超过 300,然后将其重置为 50),然后使内在内容大小无效并强制调用draw()
:Here's a quick look at using it at run-time. Each tap (anywhere) will increase the
height
property by 50 (until we get over 300, when it will be reset to 50), which then invalidates the intrinsic content size and forces a call todraw()
: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 } }
这篇关于自定义 UIView 上的 IntrinsicContentSize 拉伸内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 视图高度 =