【发布时间】:2015-04-29 09:44:53
【问题描述】:
是否可以使用基于intrinsicContentSize 动态计算的纵横比来应用此类自动布局约束?
在文档中,我发现只有具有固定比率值的约束。
intrinsicContentSize 的实际高度和高度在我的用例中并不重要,我想保留动态变化的视图的高度和宽度比。
我应该提供我自己的约束实现吗?还是有更好的办法?
【问题讨论】:
标签: ios objective-c macos autolayout
是否可以使用基于intrinsicContentSize 动态计算的纵横比来应用此类自动布局约束?
在文档中,我发现只有具有固定比率值的约束。
intrinsicContentSize 的实际高度和高度在我的用例中并不重要,我想保留动态变化的视图的高度和宽度比。
我应该提供我自己的约束实现吗?还是有更好的办法?
【问题讨论】:
标签: ios objective-c macos autolayout
intrinsicContentSize 不可用作约束的输入。 (从逻辑上讲,实现intrinsicContentSize 和相关的内容拥抱和抗压缩优先级存在一些约束,但这是不同的。)
如果您想要这样的纵横比约束,您必须自己添加它。在给定时刻查询intrinsicContentSize 很容易,验证它是否为两个维度提供了真实值(不是NSViewNoInstrinsicMetric),计算纵横比,然后将其用作与项目宽度相关的约束中的乘数到它的高度。
困难的部分是知道intrinsicContentSize 何时失效,以便您可以删除旧的纵横比约束并添加一个新约束。您可以通过覆盖-invalidateIntrinsicContentSize 将其作为视图的子类来实现。 (一定要打电话给 super!)但是,我不知道有什么方法可以从控制器或超级视图中做到这一点。
【讨论】:
您可以找到有关如何设置基于比率的约束here 的答案。您只需将宽度和高度限制在一起,同时保持给定的纵横比(在这种情况下为 4/3)。
我们可以争论视图知道这些信息是否是一件好事,或者他们的父母是否应该设置这种约束。我通常更喜欢父母设置约束,但是如果你的视图没有任何意义没有这个约束或者所有这些视图都需要这个约束,你可以安全地让这些视图管理它们自己的宽度/高度比。
最后,intrinsicContentSize 告诉 Auto Layout 当视图是单独的时视图的大小:
返回接收视图的自然大小,仅考虑视图本身的属性。
我不知道你的观点代表什么,但正如文档所说,你可以返回CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric):
如果自定义视图没有给定维度的固有大小,它可以返回该维度的 UIViewNoIntrinsicMetric。
【讨论】:
如果你有想在运行时计算约束值的情况,最好的选择是CTRL将约束拖到控制器的.h文件中并创建一个IBOutlet为了它。这允许您更改代码中约束的值。您甚至可以对约束值的更改进行动画处理。
然后在您的代码中,在设置时或发生可能更改您想要的值的操作(例如加载新图像)时,您计算您想要的约束值并在代码中设置它的值。通常你会这样做:
self.myConstraintIBOutlet.constant = <insert your new value>;
然后您可能需要将受影响的视图标记为需要布局:
// Mark whole view as needing layout. You could do this in a subview if
// only a small area is affected
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
如果你想要一个平滑的过渡,你可以把layoutIfNeeded放在一个动画块中,让它动画约束的变化:
[self.view setNeedsLayout];
[UIView animateWithDuration:.25 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
// Completion code
}];
【讨论】:
self.myConstraintIBOutlet.constant = self.someView.intrinsicContentSize.height / self.someView.intrinsicContentSize.width;。它应该在所有视图布局更新之前。
viewWillAppear 将是一个起点,因为此时视图具有它们的大小。如果您稍后将其留给viewDidAppear,您会看到布局更改,这可能看起来像一个小故障。
constant中,而是在multiplier中。创建约束后,您无法更改其multiplier。