gpt4 book ai didi

ios - 移除所有影响 UIView 的约束

转载 作者:IT老高 更新时间:2023-10-28 11:26:37 30 4
gpt4 key购买 nike

我有一个 UIView,它通过几个约束放置在屏幕上。一些约束归父 View 所有,其他约束归其他祖先所有(例如,可能是 UIViewController 的 View 属性)。

我想删除所有这些旧约束,并使用新约束将其放置在新的地方。

如何在不为每个约束创建 IBOutlet 并且不必记住哪个 View 拥有所述约束的情况下做到这一点?

详细地说,天真的方法是为每个约束创建一堆 IBOutlets,然后会涉及调用代码,例如:

[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];

这段代码的问题是,即使在最简单的情况下,我也需要创建 2 个 IBOutlets。对于复杂的布局,这可以轻松达到 4 或 8 个所需的 IBOutlets。此外,我需要确保在正确的 View 上调用删除约束的调用。例如,假设 myViewsLeftConstraintviewA 所有。如果我不小心调用了 [self.view removeConstraint:self.myViewsLeftConstraint],什么都不会发生。

注意:方法constraintsAffectingLayoutForAxis看起来很有希望,但仅用于调试目的。


更新:我收到的许多答案都涉及 self.constraintsself.superview.constraints 或其中的一些变体.这些解决方案不起作用,因为这些方法只返回 View 拥有的约束,而不是影响 View 的约束。

要阐明这些解决方案的问题,请考虑以下 View 层次结构:

  • 祖父
    • 父亲
        • 儿子
        • 女儿
      • 兄弟
    • 大叔

现在假设我们创建了以下约束,并始终将它们附加到它们最近的共同祖先:

  • C0:我:与儿子同顶(归我所有)
  • C1:我:宽度 = 100(归我所有)
  • C2:我:和哥哥一样高(父亲拥有)
  • C3:我:和叔叔(祖父所有)同顶
  • C4:我:与祖父相同(由祖父拥有)
  • C5:兄弟:与父亲同左(父亲拥有)
  • C6:叔叔:与祖父同左(祖父所有)
  • C7:儿子:与女儿相同的左边(归我所有)

现在假设我们想要移除所有影响 Me 的约束。任何适当的解决方案都应该删除 [C0,C1,C2,C3,C4] ,仅此而已。

如果我使用 self.constraints(self 是我),我将得到 [C0,C1,C7],因为这些是我拥有的唯一约束.显然,删除它是不够的,因为它缺少 [C2,C3,C4]。此外,它会不必要地删除 C7

如果我使用 self.superview.constraints(其中 self 是 Me),我将得到 [C2,C5],因为这些是父亲拥有的约束。显然我们无法删除所有这些,因为 C5Me 完全无关。

如果我使用 grandfather.constraints,我会得到 [C3,C4,C6]。同样,我们不能删除所有这些,因为 C6 应该保持原样。

蛮力方法是遍历每个 View 的祖先(包括它自己),并查看 firstItemsecondItem 是否是 View 本身;如果是这样,请删除该约束。这将导致正确的解决方案,返回 [C0,C1,C2,C3,C4],并且只返回那些约束。

但是,我希望有一个比遍历整个祖先列表更优雅的解决方案。

最佳答案

这种方法对我有用:

@interface UIView (RemoveConstraints)

- (void)removeAllConstraints;

@end


@implementation UIView (RemoveConstraints)

- (void)removeAllConstraints
{
UIView *superview = self.superview;
while (superview != nil) {
for (NSLayoutConstraint *c in superview.constraints) {
if (c.firstItem == self || c.secondItem == self) {
[superview removeConstraint:c];
}
}
superview = superview.superview;
}

[self removeConstraints:self.constraints];
self.translatesAutoresizingMaskIntoConstraints = YES;
}

@end

执行完成后,您的 View 会保持在原来的位置,因为它会创建自动调整大小的约束。当我不这样做时, View 通常会消失。此外,它不仅从父 View 中移除约束,而且一直向上遍历,因为在祖先 View 中可能存在影响它的约束。


Swift 4 版本

extension UIView {

public func removeAllConstraints() {
var _superview = self.superview

while let superview = _superview {
for constraint in superview.constraints {

if let first = constraint.firstItem as? UIView, first == self {
superview.removeConstraint(constraint)
}

if let second = constraint.secondItem as? UIView, second == self {
superview.removeConstraint(constraint)
}
}

_superview = superview.superview
}

self.removeConstraints(self.constraints)
self.translatesAutoresizingMaskIntoConstraints = true
}
}

关于ios - 移除所有影响 UIView 的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24418884/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com