手动布局中的自动布局

7

我能否在使用frame,bounds,autoresizingMask定位的父视图中添加使用autolayout的子视图?

通常情况下,我们看到的是相反的情况,但我无法实现这种情况。

编辑: 我为大家添加了一些代码。只需创建一个新的Xcode项目并在为我们创建的ViewController.swift上粘贴以下代码即可。

class ViewController: UIViewController
{

    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let custom = CustomManualLayoutSubviews()
        let subview = UIView()
        let childView = UIView()

        custom.backgroundColor = UIColor.red
        subview.backgroundColor = UIColor.green
        childView.backgroundColor = UIColor.blue

        custom.translatesAutoresizingMaskIntoConstraints = false
        subview.translatesAutoresizingMaskIntoConstraints = false
        childView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(custom)
        custom.addSubview(subview)
        subview.addSubview(childView)

        pin(child: custom, parent: view)
        pin(child: childView, parent: subview)
    }

    private func pin(child: UIView, parent: UIView) {
        parent.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[view]-10-|", options: [], metrics: nil, views: ["view" : child]))
        parent.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]-10-|", options: [], metrics: nil, views: ["view" : child]))
    }
}


class CustomManualLayoutSubviews : UIView
{
    override func layoutSubviews() {
        super.layoutSubviews()

        for subview in subviews {
            subview.frame = bounds.insetBy(dx: 10, dy: 10)
            print("subview frame: \(subview)")
        }
    }
}

从代码中可以看出,subview使用了手动布局而custom和childView使用了自动布局。但结果是使用自动布局的childView未显示在屏幕上,检查后发现其宽度和高度均为0。
如图所示,没有任何蓝色区域显示。

你想用代码实现吗? - Onik IV
当然!这是不可能由IB完成的。 - mohamede1945
目前在IB中可以制作许多条件语句。 - Onik IV
不添加自动布局约束,你可以通过边界完成。请参考这个教程:http://www.informit.com/articles/article.aspx?p=2015112&seqNum=3 - Lydia
注释掉 subview.translatesAutoresizingMaskIntoConstraints = false 将解决你的问题。这行代码阻止了 CustomManualLayoutSubviews.layoutSubviews() 的生效。 - DawnSong
3个回答

3
是的,但你必须非常小心,并且相当受限制。
从技术上讲,如果窗口中的任何视图都使用自动布局,则窗口中的所有内容都使用自动布局。只是那些`translatesAutoresizingMaskIntoConstraints`属性保持开启的视图的约束会从`frame`和`autoresizingMask`自动生成。
因此,您必须确保您的约束不干扰那些自动生成的约束。您可以使用`translatesAutoresizingMaskIntoConstraints`松散地挂接视图,但是您的约束不能“推”或“拉”这些视图。使用`translatesAutoresizingMaskIntoConstraints`的视图必须完全自由移动和调整大小。
例如,您可以使用约束将按钮定位在容器视图的前端内部,但是如果您还将其限制为后沿,则最好使其内容吸附和压缩阻力优先级非常低,以便它们不会尝试更改容器的宽度。即使这样,您可能仍会遇到冲突。在自动布局中,视图的宽度不允许变成负数。如果容器设置为零宽度且按钮与边缘的距离为非零,则会出现冲突。因此,后沿的约束也应该具有低优先级,以便在必要时可以打破它(或者您可以针对前沿这样做)。
您说您无法在使用`translatesAutoresizingMaskIntoConstraints`的视图中使用自动布局。如果您需要进一步帮助,则需要解释您尝试了什么以及尝试时发生了什么。

谢谢你的回答!我添加了一些代码以更详细地解释这个问题。 - mohamede1945
任何你设置了其框架、边界或位置的视图都应该将 translatesAutoresizingMaskIntoConstraints 设置为 true,并且不应该设置决定其位置的约束。此外,如果你在 layoutSubviews() 的重写中设置了这些属性,你应该在修改它们后再次调用 super。因此,在你的情况下,不要调用 subview.setTranslatesAutoresizingMaskIntoConstraints(false) 并在 layoutSubviews() 的末尾添加第二个调用 super.layoutSubviews() - Ken Thomases
非常感谢。如果您能修复上面的代码并给我一个修好的版本,我会接受它作为答案。 - mohamede1945
还可以参考http://oleb.net/blog/2014/03/how-i-learned-to-stop-worrying-and-love-auto-layout/。它说:“您还应该在视图上设置translates​Autoresizing​Mask​Into​Constraints = NO,因为无论如何都要手动定位和调整其大小。” - mohamede1945

1
是的。一旦一个视图启用了自动布局,整个窗口都会启用自动布局,将框架转换为顶部、左侧、宽度和高度约束(考虑自动调整掩码)。
因此,即使您认为您正在操作框架或边界或中心属性,它也会在幕后转换为自动布局,使其与您启用自动布局的视图完全兼容。

谢谢你的回答!我添加了一些代码来更详细地解释问题。 - mohamede1945

0

谢谢你的回答!我添加了一些代码来更详细地解释问题。 - mohamede1945

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接