如何在嵌套视图中使用preservesSuperviewLayoutMargins

Sam*_*Sam 5 iphone uikit ios swift

我试图preservesSuperviewLayoutMargins通过嵌套的视图层次结构使用,但是在UIKit遇到了很多问题,并想知道我做错了什么(或者这是否是一个真正的错误).

我试图布置一些视图(一些在彼此的旁边,一些在彼此之上),如下:

// Various combinations here will create different visual results (it will either work or won't)

let i1 = ImageView()
//let i1 = LabelView()
let i2 = ImageView()
//let i2 = LabelView()
let i3 = ImageView()
//let i3 = LabelView()

let view = LeftRight(left: i1, right: TopBottom(top: i2, bottom: i3))
//let view = LeftRight(left: TopBottom(top: i2, bottom: i3), right: i1)
Run Code Online (Sandbox Code Playgroud)

有了一些布局,我可以让它工作,如下所示.您可以看到右侧的图像正确缩进绿色视图,而绿色视图又正确地缩进白色视图.

正确嵌入

但与其他人一起,我正在努力:

黑屏!

在应用程序中运行与此类似的代码我可以获得完整的锁定和内存失控.

缩进是这样完成的layoutMargins:

let masterView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
masterView.translatesAutoresizingMaskIntoConstraints = false
masterView.layoutMargins = UIEdgeInsets(top: 5.0, left: 5.0, bottom: 5.0, right: 5.0)

let subView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
subView.translatesAutoresizingMaskIntoConstraints = false
subView.layoutMargins = UIEdgeInsets(top: 5.0, left: 5.0, bottom: 5.0, right: 5.0)
Run Code Online (Sandbox Code Playgroud)

这是一个操场上的图像布局示例.完整的游乐场项目可以在这里找到,可以很容易地加载并在XCode中运行,看看我的意思.

class ImageView: UIView {

    init() {

        super.init(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))

        self.preservesSuperviewLayoutMargins = true
        self.layoutMargins = .zero

        let imageView = UIImageView(image: UIImage(named: "jesus"))
        imageView.contentMode = .center

        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.clipsToBounds = true
        self.clipsToBounds = true
        imageView.backgroundColor = UIColor.red

        self.addSubview(imageView)

        imageView.leftAnchor.constraint(equalTo: self.layoutMarginsGuide.leftAnchor).isActive = true
        imageView.rightAnchor.constraint(equalTo: self.layoutMarginsGuide.rightAnchor).isActive = true
        imageView.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: self.layoutMarginsGuide.bottomAnchor).isActive = true
    }
}
Run Code Online (Sandbox Code Playgroud)

Mih*_*atu 0

好的。找到你的问题了 您的主视图和子视图都有大小为 500x500 的框架和每边 5 点的 marginLayout。如果你用框架实例化它们,.zero那么一切都应该没问题。

更新

在花了更多时间在 Playground 上之后,我还将其添加到 ImageView 中:

private var imageView: UIImageView!
override var intrinsicContentSize: CGSize {
    return imageView?.intrinsicContentSize ?? .zero
}
Run Code Online (Sandbox Code Playgroud)

和标签视图:

private var textLabel: UILabel!
override var intrinsicContentSize: CGSize {
    return textLabel?.intrinsicContentSize ?? .zero
}
Run Code Online (Sandbox Code Playgroud)

现在,在两者的 init 方法中ImageViewLabelView使用这些实例属性而不是局部变量。这样做之后,似乎所有可能的组合都有效。如果您有一种您不知道的特定组合,请告诉我,以便我测试它。