ios - 为什么设置前导和尾随 anchor 不起作用但宽度呢?

标签 ios

我无法弄清楚为什么将前导和尾随 anchor 设置到 View 不起作用,但是当我设置宽度时它确实起作用。
我有一个 UIStackViewUIScrollView 内,这就是我设置我的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),
    ])
}

这就是我设置 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)
        ])
    }

出于某种原因,UIStackView只占用大约一半的屏幕,但是,当更改 scrollView.leadingself.leading对于 trailing同样,这确实有效,UIStackView被拉伸(stretch)以适应几乎整个屏幕的宽度。
将宽度设置为 UIScreen 边界的 0.95 也可以。

所以,我的问题是,为什么当我使用 self它确实有效,但 scrollView才不是?
我确实调用 setupScrollView之前 setupTextfieldsStackscrollView正确渲染。

最佳答案

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

Technical Note TN2154 , 他们说:

In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. That is, if you pin a view to the left edge of its superview, you’re really pinning it to the minimum x-value of the superview’s bounds. Changing the bounds origin of the superview does not change the position of the view.

The UIScrollView class scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the top, left, bottom, and right edges within a scroll view now mean the edges of its content view.

The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the scroll view. (This should not be confused with the intrinsicContentSize method used for Auto Layout.) To size the scroll view’s frame with Auto Layout, constraints must either be explicit regarding the width and height of the scroll view, or the edges of the scroll view must be tied to views outside of its subtree.

Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints between the view and a view outside the scroll view’s subtree, such as the scroll view’s superview.



通过在 ScrollView 的 subview 和“ ScrollView 的子树之外的 View ”之间添加约束来解决这个问题的建议有点过时了。在 iOS 9 中,他们引入了一些布局指南来解决这个问题,即 contentLayoutGuide frameLayoutGuide .前者用于定义 ScrollView 的contentSize (即滚动行为),后者用于定义 subview 的 frame相对于 ScrollView 。

因此,当向 ScrollView 添加 subview 时,您通常希望将所有四个顶部、底部、前导和尾随约束设置为 ScrollView 的 contentLayoutGuide (所以它正确滚动)。然后定义 ScrollView 的 frameLayoutGuide 的前导和尾随 anchor (以确保 subview 具有适当的宽度):
NSLayoutConstraint.activate([
    textfieldsStack.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 16),
    textfieldsStack.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -16),
    textfieldsStack.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 8),
    textfieldsStack.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -8),

    textfieldsStack.leadingAnchor.constraint(equalTo: scrollView.frameLayoutGuide.leadingAnchor, constant: 16),
    textfieldsStack.trailingAnchor.constraint(equalTo: scrollView.frameLayoutGuide.trailingAnchor, constant: -16)
])

关于ios - 为什么设置前导和尾随 anchor 不起作用但宽度呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62158070/

相关文章:

ios - 标注注释 View 不可点击中心

ios - 尝试在 USerDefault 中保存图像时我做错了什么

ios - 如何使用 TwilioXamarinBindings Twilio.Voice.iOS 接听来电

ios - 如何在 ImageIO iOS 框架中升级图像?

ios - 如何在 Objective-C 中使用 for 循环替换 HTML 值?

iphone - 如何在 UIImageView 上制作可点击的 UIButton?

ios - Swift 中的单行 if 语句

ios - session 过期设计模式

ios - 对 JSON 日期进行排序

ios - appDelegate 的 alertView 不会切换 View uppon buttonIndex