为什么设置前导和尾随锚点不起作用,但设置宽度却起作用?

Joh*_*oah 3 ios

我不明白为什么设置视图的前导和尾随锚点不起作用,但是当我设置宽度时它确实起作用。我有一个UIStackView内部 a UIScrollView,这就是我设置的方式UIScrollView

private func setupScrollView() {
    addSubview(scrollView)
    NSLayoutConstraint.activate([
        scrollView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
        scrollView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
        scrollView.topAnchor.constraint(equalTo: backButton.bottomAnchor),
        scrollView.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor),
    ])
}
Run Code Online (Sandbox Code Playgroud)

这就是我设置的方式UIStackView

        private func setupTextfieldsStack() {
        scrollView.addSubview(textfieldsStack)
        let height = UIScreen.main.bounds.height * 0.35
        NSLayoutConstraint.activate([
            textfieldsStack.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16),
            textfieldsStack.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16),
            textfieldsStack.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 8),
            textfieldsStack.heightAnchor.constraint(equalToConstant: height)
        ])
    }
Run Code Online (Sandbox Code Playgroud)

由于某种原因,UIStackViewonly 占据了大约一半的屏幕,但是,当更改scrollView.leadingself.leading和 fortrailing时,这确实有效,并且UIStackView被拉伸以适应屏幕的几乎整个宽度。将宽度设置为 UIScreen 边界的 0.95 也可以。

所以,我的问题是,为什么当我使用self它时它可以工作但scrollView不起作用?我setupScrollView之前确实调用过setupTextfieldsStack并且scrollView渲染正确。

Rob*_*Rob 6

当在滚动视图及其子视图之间设置约束时,默认情况下,这些约束将用于计算contentSize滚动视图的(即定义滚动行为),但不会对子视图的大小施加任何约束。

\n\n

技​​术说明 TN2154中中,他们说:

\n\n
\n

一般来说,自动布局将视图的上、左、下、右边缘视为可见边缘。也就是说,如果将视图固定到其超级视图的左边缘,则实际上将其固定到超级视图边界的最小 x 值。更改超级视图的边界原点不会更改视图的位置。

\n\n

UIScrollView通过更改其边界的原点来滚动其内容。为了使此功能与自动布局一起使用,滚动视图中的顶部、左侧、底部和右侧边缘现在表示其内容视图的边缘。

\n\n

对滚动视图子视图的约束必须导致要填充的大小,然后将其解释为滚动视图的内容大小。(这不应与intrinsicContentSize自动布局所使用的方法混淆。)要使用自动布局调整滚动视图\xe2\x80\x99s 框架的大小,必须对滚动视图的宽度和高度或滚动视图的边缘进行明确的约束。滚动视图必须与其子树外部的视图相关联。

\n\n

请注意,您可以通过在视图和滚动视图\xe2\x80\x99s 子树外部的视图(例如滚动视图)之间创建约束,使滚动视图的子视图看起来浮动(而不是滚动)在其他滚动内容上。 xe2\x80\x99s 超级视图。

\n
\n\n

通过在滚动视图\xe2\x80\x99s子视图和滚动视图\xe2\x80\x99s子树\xe2\x80\x9d之外的\xe2\x80\x9ca视图之间添加约束来解决这个问题的建议有点过分了日期。在 iOS 9 中,他们引入了一些解决这个问题的布局指南,即contentLayoutGuideframeLayoutGuide. 前者用于定义滚动视图\xe2\x80\x99s contentSize(即滚动行为),后者用于定义子视图\xe2\x80\x99sframe相对于滚动视图的子视图\xe2\x80\x99s。

\n\n

因此,当向滚动视图添加子视图时,您通常需要将所有四个顶部、底部、前导和尾随约束设置为滚动视图\xe2\x80\x99s contentLayoutGuide(以便它正确滚动)。然后定义滚动视图的前导和尾随锚点\xe2\x80\x99sframeLayoutGuide(以确保子视图具有适当的宽度):

\n\n
NSLayoutConstraint.activate([\n    textfieldsStack.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 16),\n    textfieldsStack.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -16),\n    textfieldsStack.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 8),\n    textfieldsStack.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -8),\n\n    textfieldsStack.leadingAnchor.constraint(equalTo: scrollView.frameLayoutGuide.leadingAnchor, constant: 16),\n    textfieldsStack.trailingAnchor.constraint(equalTo: scrollView.frameLayoutGuide.trailingAnchor, constant: -16)\n])\n
Run Code Online (Sandbox Code Playgroud)\n