swift 为什么这个滚动视图不显示子视图?

swift why this scroll view does not show subview?

正在以编程方式使用滚动视图进行测试,但无法理解为什么这不起作用。逻辑希望我在主视图中添加一个滚动视图,然后将其用作文斯添加到其中的所有子视图的参考。

let myView = UIView()
let myScroll = UIScrollView()

 override func viewDidLoad() {
        super.viewDidLoad()

        myScroll.translatesAutoresizingMaskIntoConstraints = false
        myScroll.backgroundColor = UIColor.cyan
        self.view.addSubview(myScroll)

        myScroll.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 10).isActive = true
        myScroll.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10).isActive = true
        myScroll.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
        myScroll.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true

        drawView(supVi: myScroll, addedVi: myView, color4View: .red, leading: 10, right: -10, top: 10, hei: -10)

    }

    func drawView(supVi: UIView, addedVi: UIView, color4View: UIColor, leading: CGFloat, right: CGFloat, top: CGFloat, hei: CGFloat) {

        supVi.addSubview(addedVi)
        addedVi.translatesAutoresizingMaskIntoConstraints = false
        addedVi.backgroundColor = color4View

        addedVi.leadingAnchor.constraint(equalTo: supVi.leadingAnchor, constant: leading).isActive = true
        addedVi.topAnchor.constraint(equalTo: supVi.topAnchor, constant: top).isActive = true
        addedVi.rightAnchor.constraint(equalTo: supVi.rightAnchor, constant: right).isActive = true
        addedVi.heightAnchor.constraint(equalToConstant: hei).isActive = true


    }

两个观察:

  1. 您将高度限制设置为 -10。那没有任何意义。我相信您打算设置底部约束,而不是高度。

  2. 您正在设置滚动视图子视图的约束,但不会设置子视图的大小。这些约束将用于设置滚动视图的 contentSize(并且您的子视图可能以 .zeroCGRect 结束)。

    如果您单击 “调试视图层次结构”按钮,然后导航至运行时问题,您将看到“内容大小不明确”警告。

    您需要添加规定子视图大小的约束。考虑:

    let myView = UIView()
    let myScroll = UIScrollView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        myScroll.translatesAutoresizingMaskIntoConstraints = false
        myScroll.backgroundColor = .cyan
        view.addSubview(myScroll)
    
        NSLayoutConstraint.activate([
            myScroll.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            myScroll.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10),
            myScroll.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
            myScroll.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10)
        ])
    
        addView(myView, to: myScroll, color: .red, leading: 10, trailing: -10, top: 10, bottom: -10)
    }
    
    func addView(_ addedView: UIView, to superview: UIView, color: UIColor, leading: CGFloat, trailing: CGFloat, top: CGFloat, bottom: CGFloat) {
    
        superview.addSubview(addedView)
        addedView.translatesAutoresizingMaskIntoConstraints = false
        addedView.backgroundColor = color
    
        // these dictate the `contentSize` of the scroll view relative to the subview
    
        NSLayoutConstraint.activate([
            addedView.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: leading),
            addedView.topAnchor.constraint(equalTo: superview.topAnchor, constant: top),
            addedView.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: trailing),
            addedView.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: bottom)
        ])
    
        // these define the size of the `addedView`
    
        NSLayoutConstraint.activate([
            addedView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
            addedView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 2.0)
        ])
    }
    

    addView 方法的最后两个约束中,我特意将 addedView 的宽度设置为父视图的一半,将其高度设置为其父视图的两倍,这样你就可以看到如何

    • 它滚动;
    • 滚动视图的 contentSize 是通过您在 addedView 和滚动视图之间定义的神奇约束自动为您设置的;和
    • 子视图的高度实际上是由我添加到您的原始代码片段中的这两个新约束决定的。

    现在,当然,我知道您不希望它的宽度是主视图的一半,高度是主视图的两倍,我只建议您尝试这样做,这样您就可以了解它是如何工作的。您现在可以只添加 widthAnchorheightAnchor 相对于主视图,您将获得所需的效果。

    顺便说一下,不要摆脱滚动视图和它的子视图之间的约束,因为你也需要它们。但是添加上面代码段末尾显示的这些额外约束。

  3. 无关,我注意到你在设置“前导”和“右”锚点。如果您碰巧使用 RTL 语言,“前导”锚点和“右”锚点是同一回事,您永远不会设置“尾随”或“左”锚点。

    您确实要设置“前导”锚点和“尾随” 锚点,而不是“右” 锚点。始终使用“前导”和“尾随”(如果您出于某种原因不想支持 RTL 语言,则始终使用“左”和“右”)。