我无法弄清楚为什么将前导和尾随 anchor 设置到 View 不起作用,但是当我设置宽度时它确实起作用。
我有一个 UIStackView
在 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),
])
}
这就是我设置
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.leading
至self.leading
对于 trailing
同样,这确实有效,UIStackView
被拉伸(stretch)以适应几乎整个屏幕的宽度。将宽度设置为 UIScreen 边界的 0.95 也可以。
所以,我的问题是,为什么当我使用
self
它确实有效,但 scrollView
才不是?我确实调用
setupScrollView
之前 setupTextfieldsStack
和 scrollView
正确渲染。
最佳答案
在 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/