【问题标题】:Copy IB Created Constraints to another UIView将 IB 创建的约束复制到另一个 UIView
【发布时间】:2014-12-13 21:30:00
【问题描述】:

我在屏幕上列出了UITableView 以及其他视图元素。当没有要显示的交易时,我计划用另一个视图替换这个列表。为此,我需要复制附加到UITableView 的所有约束并将它们添加到新的UIView

我尝试复制 .constraints() 属性值,但它返回 nil,因为约束附加到超级视图。从superview 获取约束也会产生附加到其他子视图的所有约束。

有没有一种快速的方法可以将约束从一个UIView 复制和添加到另一个?

【问题讨论】:

    标签: ios uiview view autolayout nslayoutconstraint


    【解决方案1】:

    没有捷径。

    我已经完成了对超级视图约束的循环。

    目标-C

    + (void)copyConstraintsFromView:(UIView *)sourceView toView:(UIView *)destView
    {
        for (NSLayoutConstraint *constraint in sourceView.superview.constraints) {
            if (constraint.firstItem == sourceView)
            {
                [sourceView.superview addConstraint:[NSLayoutConstraint constraintWithItem:destView attribute:constraint.firstAttribute relatedBy:constraint.relation toItem:constraint.secondItem attribute:constraint.secondAttribute multiplier:constraint.multiplier constant:constraint.constant]];
            }
            else if (constraint.secondItem == sourceView)
            {
                [sourceView.superview addConstraint:[NSLayoutConstraint constraintWithItem:constraint.firstItem attribute:constraint.firstAttribute relatedBy:constraint.relation toItem:destView attribute:constraint.secondAttribute multiplier:constraint.multiplier constant:constraint.constant]];
            }
        }
    }
    

    斯威夫特

    static func copyConstraints(fromView sourceView: UIView, toView destView: UIView) {
        guard let sourceViewSuperview = sourceView.superview else {
            return
        }
        for constraint in sourceViewSuperview.constraints {
            if constraint.firstItem as? UIView == sourceView {
                sourceViewSuperview.addConstraint(NSLayoutConstraint(item: destView, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: constraint.secondItem, attribute: constraint.secondAttribute, multiplier: constraint.multiplier, constant: constraint.constant))
            } else if constraint.secondItem as? UIView == sourceView {
                sourceViewSuperview.addConstraint(NSLayoutConstraint(item: constraint.firstItem, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: destView, attribute: constraint.secondAttribute, multiplier: constraint.multiplier, constant: constraint.constant))
            }
        }
    }
    

    注意

    记住在将 destView 添加到视图层次结构后只复制约束。

    【讨论】:

      【解决方案2】:

      不,系统中没有为此内置任何内容。

      NSLayoutConstraint 对象是不可变的,除了它的constant 优先级之外,因此一旦创建了对象,您就不能简单地将“相同”约束应用于另一个视图(其中“相同”表示对象标识或对象相等)。

      如果性能允许,而不是设置和拆除视图及其所有约束,我只需将表视图和无数据对应视图设置为同级视图,使用一个辅助函数在每个视图上安装等效约束,这样它们的布局相同,但一个在另一个之上。然后我就用hidden 属性交换哪个视图可见。

      但是,如果您真的想在运行时将一个视图的约束复制到另一个视图上,一般来说,您必须编写一个实用程序方法,该方法从最原始的超级视图开始进行递归搜索,该超级视图可能有约束影响正在复制的视图,并创建应用于另一个视图的重复约束。这样的函数可能已经写在 AL 帮助程序库之一中,例如 FLKAutoLayout。

      【讨论】:

      • 好吧,我最终也在 IB 中为另一个视图创建了约束。编写递归查找的方法是一团糟,因为约束也可能与兄弟姐妹有关。
      猜你喜欢
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多