以编程方式删除在界面构建器中设置的 IBOutlet 并使用相同的约束再次添加它

Remove IBOutlet programmatically that is set in interface builder and add it again with same constraints

假设我在 .nib 文件中有一个 ViewController,其中 IBOutlet imageView 作为带有约束的子视图,imageView 连接到与 nib 文件关联的 ViewController class .现在,我使用以下代码删除 imageView:

imageView.removeFromSuperview()

稍后我想再次将它添加到 ViewController 视图中,其约束与我在删除 imageView 之前在界面构建器中设置的约束相同。我的问题是:

  1. 是否可以在不再次初始化 ViewController 的情况下在代码中执行此操作?
  2. 如果我在删除图像视图后以编程方式将其作为子视图添加到 VC,则约束将不再可用。我真的很想跳过在代码中再次设置约束,因为它们已经存在于界面构建器中,这可能吗?

我想你可以像这样隐藏图像视图:

imageView.isHidden = true

imageView.alpha = 0

否则,您可以将约束存储在某处并稍后将其添加回适当的视图。

一种方法是将约束保存在 var 中,然后以编程方式将它们重新设置。顺便说一句,因为 IBOutlet 很弱,一旦你删除它,你就不能再添加 imageView 了。所以你必须保持一个强大的参考。删除 imageView 也会干扰其他具有依赖约束的视图。但是,如果其他视图的约束独立于您的 imageView,则不会有问题。
另一种方法是引用您的 imageView 的高度或宽度约束并将其常量更改为零,以实际上使其从您的视图中消失。这样,您只需将约束更改回其原始值即可取消隐藏,并确保自动调整其他视图的约束。

理论上,您可以在视图控制器中,在删除图像视图之前保存约束,如下所示:

let savedConstraints = view.constraints.filter { (constraint) -> Bool in
    constraint.firstItem as? UIView == myImageView || constraint.secondItem as? UIImageView == myImageView
}

... 其中 myImageView 是您要删除的图像视图。上面的检查读取连接到您的视图的约束和 returns 连接到您的图像视图的约束。

然后您可以在创建新图像视图时重新添加这些约束:

let myNewImageView = UIImageView()
view.addSubview(myNewImageView)
savedConstraints.forEach { (constraint) in
    view.addConstraint(NSLayoutConstraint(
            item: view,
            attribute: constraint.firstAttribute,
            relatedBy: constraint.relation,
            toItem: myNewImageView,
            attribute: constraint.secondAttribute,
            multiplier: constraint.multiplier,
            constant: constraint.constant))
}

虽然我同意建议隐藏图像视图的评论者。