使用 Masonry 向视图的子视图添加自动布局约束

Posted

技术标签:

【中文标题】使用 Masonry 向视图的子视图添加自动布局约束【英文标题】:Adding auto-layout constraints to subviews of a view with Masonry 【发布时间】:2015-01-28 21:10:14 【问题描述】:

我正在使用 Masonry ios 库来简化一些围绕 iOS 自动布局的逻辑,并且到目前为止我很喜欢它。不过,就在最近,我正在开发一个更复杂的应用程序,并尝试将自动布局约束添加到与其父视图相关的子视图中。然而,这样做似乎会迫使父视图采用其子视图的约束。可能我只是没有完全理解自动布局继承的这一方面,但这里有一个简单的例子:

UIView *test = UIView.new;
[test setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:test];
[test makeConstraints:^(MASConstraintMaker *make) 
    make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
];

UIView *test2 = UIView.new;
[test2 setBackgroundColor:[UIColor redColor]];
[test addSubview:test2];
[test2 makeConstraints:^(MASConstraintMaker *make) 
    make.edges.equalTo(test).with.insets(UIEdgeInsetsMake(5, 5, 5, 5));
    make.centerX.equalTo(test);
];

在这个例子中,尽管第二个 UIView (test2) 是 test 的一个子视图,并且它的边缘设置为匹配 test,但当这段代码运行时,“test”视图被推到与屏幕齐平。奇怪的是,顶部和底部似乎尊重“测试”视图的边缘插图,并且它们准确定位自己,但是“视图”的右边缘现在位于 20 点插图处(因为左侧与左侧齐平)。

现在如果我改变 test2 并使其成为 self.view 而不是的子视图测试约束突然就可以正常工作了。

这是当 test2 是 test 的子视图时发生的情况的直观图片:

这似乎意味着您只能将相关约束添加到同一个父视图的子视图。我知道这不可能,但尽管尝试了各种不同的事情,但我似乎无法阻止更深层次的子视图影响他们的父母。

【问题讨论】:

您是否在控制台中看到任何关于模糊约束的警告? 不,没有。这也是我的第一个想法,但似乎自动布局逻辑认为这正是我想要的,不知何故。我还要注意删除第二个上的“centerX”约束没有影响。 【参考方案1】:

在我的情况下,问题的原因是放置在视图控制器的基本视图上的约束。该约束,最初是为了简单地将基本视图定位在全宽和全高,实际上是设置宽度、高度和顶部位置,但没有左侧位置。

让左侧位置不受任何约束会导致未来的子视图(它们本身包含左侧约束)推动父视图以符合子视图约束。

这里的教训:从您的视图堆栈的最开始开始,并在假设问题出在您的子视图之前验证您的每个子视图。

【讨论】:

以上是关于使用 Masonry 向视图的子视图添加自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将自动布局约束添加到恒定宽度和高度的子视图

使用自动布局向 UIScrollView 添加动态大小的视图(高度)

带有子视图的自动布局 NSCollectionView

使用自动布局删除和重新添加子视图

向添加到 UIWindow 的视图添加约束时,为啥无法设置自动布局约束?

以编程方式在子类 UIView 的子视图上自动布局