Autolayout宽高比基于`intrinsicContentSize`(非常数)

时间:2015-04-29 09:44:54

标签: ios objective-c macos autolayout

是否可以根据intrinsicContentSize动态计算纵横比来应用此类自动布局约束? 在文档中我发现只有固定比率值的约束。

intrinsicContentSize的实际值和高度在我的用例中并不重要,我希望保留动态变化的视图的高度和宽度比。

我应该提供自己的约束实现吗?或者有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

intrinsicContentSize不可用作约束的输入。 (逻辑上,存在实现 intrinsicContentSize以及相关内容拥抱和抗压优先级的约束,但这有不同。)

如果您想要这样的宽高比限制,您必须自己添加它。在给定时刻查询intrinsicContentSize很容易,验证它为两个维度提供实际值(不是NSViewNoInstrinsicMetric),计算宽高比,然后将其用作乘数在约束中,将项目的宽度与其高度相关联。

困难的部分是知道intrinsicContentSize何时失效,因此您可以删除旧的宽高比约束并添加新的宽高比约束。您可以通过覆盖-invalidateIntrinsicContentSize将其作为视图的子类。 (一定要打电话给超级!)但是,我不知道从控制器或超级视图那样做的方法。

答案 1 :(得分:0)

您可以找到有关如何设置基于比率的约束here的答案。您所需要的只是将宽度和高度约束在一起,保持给定的宽高比(在这种情况下为4/3)。

我们可以辩论,了解这些信息或者他们的父母是否应该设置这种限制是一件好事。我通常更喜欢父母设置约束,但如果您的视图没有任何意义没有此约束或所有这些视图都需要此约束,您可以安全地让这些视图管理自己的宽度/高度比。

最后,intrinsicContentSize告诉自动布局视图大小

  

仅考虑视图本身的属性,返回接收视图的自然大小。

我不知道您的观点代表什么,但正如文档所述,您可以返回CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric)

  

如果自定义视图没有给定维度的内在大小,则可以为该维度返回UIViewNoIntrinsicMetric。

答案 2 :(得分:0)

如果您想要在运行时计算约束的值,最好的选择是 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
        }];