intrinsicContentSize和sizeThatFits的正确用法:上UIView子类与自动布局 [英] Proper usage of intrinsicContentSize and sizeThatFits: on UIView Subclass with autolayout

查看:4415
本文介绍了intrinsicContentSize和sizeThatFits的正确用法:上UIView子类与自动布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问这(某种程度上)简单的问题,只是要挑剔,因为有时候我担心滥用我可能会做很多的UIView API的,尤其是当它涉及到自动布局。

I'm asking this (somehow) simple question just to be finicky, because sometimes I'm worried about a misuse I might be doing of many UIView's APIs, especially when it comes to autolayout.

要使它超级简单的,我会​​用一个例子去,让我们假设我需要有一个形象的图标和一个多标签的UIView子类;我想要的行为是我的观点的高度与标签的高度变化(以适应内的文本),另外,我也奠定了它与界面生成器,所以我有这样的事情:

To make it super simple I'll go with an example, let's assume I need an UIView subclass that has an image icon and a multiline label; the behaviour I want is that the height of my view changes with the height of the label (to fit the text inside), also, I'm laying it out with Interface builder, so I have something like this:

用一些限制,让固定的宽度和高度的图像视图,和固定的宽度和位置(相对于图像视图),以在标签

with some constraints that give fixed width and height to the image view, and fixed width and position (relative to the image view) to the label:

现在,如果我设置一些文本的标签,我想以高度正确地适应它,或保持与它在厦门国际银行在同一高度被调整。
自动布局之前,我会一直做这样的事情:

Now, if I set some text to the label, I want the view to be resized in height to fit it properly, or remain with the same height it has in the xib. Before autolayout I would have done always something like this:

在CustoView子文件我会重写 sizeThatFits:像这样:

In the CustoView subclass file I would have overridden sizeThatFits: like so:

- (CGSize) sizeThatFits:(CGSize)size{

    //this stands for whichever method I would have used
    //to calculate the height needed to display the text based on the font
    CGSize labelSize = [self.titleLabel intrinsicContentSize];

    //check if we're bigger than what's in ib, otherwise resize
    CGFloat newHeight = (labelSize.height <= 21) ? 51: labelSize.height+20;

    size.height = newHeight;

    return size;

}

和比我会叫这样的:

myView.titleLabel.text = @"a big text to display that should be more than a line";
[myView sizeToFit];

现在,在约束中思考,我知道,自动布局系统的呼叫 intrinsicContentSize 在视图树元素,以了解它们的大小是什么,使其计算,因此我应该重写 intrinsicContentSize 在我的子视图返回它在 sizeThatFits返回完全一样的东西:方法previously所示,除了事实证明,previously,打电话时 sizeToFit 我有我的观点正确调整,但现在有了自动布局,在与厦门国际银行的组合,这是不会发生的。

Now, thinking in constraints, I know that autolayout systems calls intrinsicContentSize on the view tree elements to know what their size is and make its calculations, therefore I should override intrinsicContentSize in my subview to return the exact same things it returns in the sizeThatFits: method previously shown, except for the fact that, previously, when calling sizeToFit I had my view properly resized, but now with autolayout, in combination with a xib, this is not going to happen.

当然,我可能会被呼召 sizeToFit 每次我在子类中编辑文本,随着时间重写 intrinsicContentSize 返回的 sizeThatFits完全相同的尺寸:,但不知何故,我不认为这是做这件事的正确方法

Of course I might be calling sizeToFit every time I edit text in my subclass, along with an overridden intrinsicContentSize that returns the exact same size of sizeThatFits:, but somehow I don't think this is the proper way of doing it.

我在想重写 needsUpdateConstraints updateConstraints ,但仍然让没有太大意义,因为我的观点的宽度和高度被推断和翻译从厦门国际银行在自动屏蔽。

I was thinking about overriding needsUpdateConstraints and updateConstraints, but still makes not much sense since my view's width and height are inferred and translated from autoresizing mask from the xib.

这么久了,你觉得什么是使正是我在这里展示并支持自动版式完全干净和最正确的方法是什么?

So long, what do you think is the cleanest and most correct way to make exactly what I show here and support fully autolayout?

推荐答案

我不认为你需要定义一个intrinsicContentSize。

I don't think you need to define an intrinsicContentSize.

下面是两个原因认为:


  1. 在自动布局文档讨论 intrinsicContentSize ,它是指它作为有关叶意见比如按钮或标签,其中一个大小可以纯粹计算基于其内容。我们的想法是,他们是在视图层次树,不是树枝叶子,因为它们不是由其他意见。

  1. When the Auto Layout documentation discusses intrinsicContentSize, it refers to it as relevant to "leaf-views" like buttons or labels where a size can be computed purely based on their content. The idea is that they are the leafs in the view hierarchy tree, not branches, because they are not composed of other views.

IntrinsicContentSize是不是真的在自动布局根本性的概念。基本概念都只是约束和限制所绑定的属性。该intrinsicContentSize,内容拥抱优先级,COM pression电阻的重点是真的只是便利,被用于生成有关大小的内部约束。最终尺寸是这些约束与以通常的方法的所有其他约束相互作用只是结果

IntrinsicContentSize is not really a "fundamental" concept in Auto Layout. The fundamental concepts are just constraints and the attributes bound by constraints. The intrinsicContentSize, the content-hugging priorities, and the compression-resistance priorities are really just conveniences to be used to generate internal constraints concerning size. The final size is just the result of those constraints interacting with all other constraints in the usual way.

还等什么?所以,如果你的自定义视图实际上只是一对夫妇的其他意见的程序集,那么你就需要定义一个intrinsicContentSize。你可以只定义为需要布局的限制,而这些限制也将产生你想要的大小。

So what? So if your "custom view" is really just an assembly of a couple other views, then you don't need to define an intrinsicContentSize. You can just define the constraints that create the layout you want, and those constraints will also produce the size you want.

在你描述的具体情况,我会从标签一个> = 0底部空间限制设置为上海华,从图像中一个又一个的上海华,然后还的低优先级为视图作为一个整体高度为零的约束。低优先级的约束将尽量缩小组装,而其他方面的限制,从迄今萎缩阻止它,它的剪辑它的子视图。

In the particular case that you describe, I'd set a >=0 bottom space constraint from the label to the superview, another one from the image to the superview, and then also a low priority constraint of height zero for the view as a whole. The low priority constraint will try to shrink the assembly, while the other constraints stop it from shrinking so far that it clips its subviews.

如果你从来没有明确定义intrinsicContentSize,你怎么看这些制约因素产生的大小?一种方法是强制布局,然后观察结果。

If you never define the intrinsicContentSize explicitly, how do you see the size resulting from these constraints? One way is to force layout and then observe the results.

另一种方法是使用 systemLayoutSizeFittingSize:(在iOS8上,小,预示着 systemLayoutSizeFittingSize:withHorizo​​ntalFittingPriority:verticalFittingPriority:)。这是一个更接近表弟 sizeThatFits: intrinsicContentSize 。它的系统会用什么来计算你的看法的适当的大小,考虑到它包含的所有限制,包括内在的内容大小限制,以及所有其他人。

Another way is to use systemLayoutSizeFittingSize: (and in iOS8, the little-heralded systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:). This is a closer cousin to sizeThatFits: than is intrinsicContentSize. It's what the system will use to calculate your view's appropriate size, taking into account all constraints it contains, including intrinsic content size constraints as well as all the others.

不幸的是,如果你有一个多行的标签,你可能还需要 preferredMaxLayoutWidth 配置得到一个好的结果,但这是另一个故事。 ..

Unfortunately, if you have a multi-line label, you'll likely also need to configure preferredMaxLayoutWidth to get a good result, but that's another story...

这篇关于intrinsicContentSize和sizeThatFits的正确用法:上UIView子类与自动布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆