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

时间:2019-01-26 16:27:34

标签: swift uiscrollview

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

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 个答案:

答案 0 :(得分:2)

两个观察结果:

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

  2. 您正在设置滚动视图的子视图的约束,但这不会设置子视图的大小。这些约束将用于设置滚动视图的contentSize(子视图可能以CGRect的{​​{1}}结尾)。

    如果您点击enter image description here(“调试视图层次结构”按钮),然后浏览到运行时问题,则会看到“内容大小模糊”的警告。

    enter image description here

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

    .zero

    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;和
    • 该子视图的高度实际上是由我添加到原始代码段中的这两个新约束所决定的。

    现在,当然,我知道您不希望它的宽度是主视图的一半,而高度却是主视图的两倍,并且我只建议您尝试一下以确保其工作原理。现在,您只需添加addedViewwidthAnchor使其相对于主视图即可获得所需的效果。

    顺便说一句,不要摆脱滚动视图及其子视图之间的约束,因为您也需要这些约束。但是,请添加上面我的代码片段结尾处显示的这些其他约束。

  3. 不相关,我注意到您正在设置“前导”和“右”锚。如果您碰巧使用RTL语言,则“前导”锚和“右”锚是同一回事,而您将永远不会设置“后移”或“左”锚。

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