以编程方式使用错误的可滚动内容大小的 UIView 对于 UIScrollView 是不明确的。只是第一次

Programmatically UIView with error Scrollable content size is ambiguous for UIScrollView. Only the first time

我的 UIViewController 包含一个 UIScrollView,我遇到了一个奇怪的行为。 ViewController 是从另一个 ViewController 推送的。视图布局如下

我设置约束和更新 stackView 内容的方式如下。

private extension PresentationViewController {

    func setupView() {
        isScrolling = true

        view.addSubview(scrollView)
        scrollView.snp.makeConstraints { (builder) in
            builder.top.left.bottom.right.equalToSuperview()
        }

        scrollView.addSubview(contenView)
        contenView.snp.makeConstraints { (builder) in
            builder.top.left.bottom.right.equalToSuperview()
            builder.width.equalToSuperview()
        }

        contenView.addSubview(headerImageView)
        headerImageView.snp.makeConstraints { (builder) in
            builder.top.left.right.equalToSuperview()
            builder.height.equalTo(view.frame.height / 2)
        }

        headerImageView.addSubview(headerTitleLabel)
        headerTitleLabel.snp.makeConstraints { (builder) in
            builder.left.right.equalToSuperview()
            builder.centerX.equalToSuperview()
            builder.centerY.equalToSuperview()
        }

        contenView.addSubview(presentationStackView)
        presentationStackView.snp.makeConstraints { (builder) in
            builder.top.equalTo(headerImageView.snp.bottom).inset(-Margins.xxLarge)
            builder.left.right.equalToSuperview()
            builder.bottom.equalTo(scrollView.snp.bottom)
        }

    }

    func updateView(presentationResponse: PresentationResponse?) {
        guard let presentationResponse = presentationResponse else { return }

        let firstPresentation = presentationResponse.presentationItems[0]
        titleView.title = presentationResponse.galleryName

        headerImageView.sd_setImage(with: URL(string: firstPresentation.imageSet.fullSize ?? ""), placeholderImage: nil)
        headerTitleLabel.text = presentationResponse.galleryName

        for item in presentationResponse.presentationItems.dropFirst() {

            let sectionImageView = UIImageView()
            sectionImageView.contentMode = .scaleAspectFit
            sectionImageView.clipsToBounds = true

            let sectionCaptionLabel = BaseLabel(withConfiguration: .headline)
            sectionCaptionLabel.text = item.rowCaption

            let sectionView = UIView()
            sectionView.addSubview(sectionImageView)
            sectionView.addSubview(sectionCaptionLabel)

            sectionImageView.sd_setImage(with: URL(string: item.imageSet.defaultImage ?? "")) { [weak self, weak sectionView] (image, error, _, _) in

                guard let strongSelf = self,
                    let sectionView = sectionView,
                    let image = image else { return }

                strongSelf.presentationStackView.addArrangedSubview(sectionView)

                sectionImageView.snp.makeConstraints { (builder) in
                    builder.top.left.bottom.equalToSuperview().inset(Margins.medium)
                    let width:CGFloat = strongSelf.view.frame.size.width / 3
                    builder.width.equalTo(width)
                    builder.height.equalTo(width * (1 / image.aspectRatioValue))

                }

                sectionCaptionLabel.snp.makeConstraints { (builder) in
                    builder.left.equalTo(sectionImageView.snp.right).inset(-Margins.medium)
                    builder.top.right.equalToSuperview().inset(Margins.medium)
                }

            }

        }

    }

}

当对后端的异步操作完成时,在 ViewDidLoad 和 updateView(:) 中触发 setupView()。

如您所见,我正在使用 Snapkit 作为我的约束。 使用调试器工具检查我的 UI 时,我收到消息:

Scrollable content size is ambiguous for UIScrollView

问题似乎与 UIStackView 有关,因为它没有显示。 但是,如果我返回并再次按下,我就没有错误,并且一切都正确显示。

只需将 Equal Height 和 Equal Width 约束添加到与主视图相关的 StackView 视图,而不是 UIScrollView。换句话说,容器视图的约束与 UIScrollView 的超级视图相关联。

之后你的 Storyboard 中将不会有警告,你可以继续为你的子视图添加约束。

如果布局显示正确,您真的不需要担心

Scrollable content size is ambiguous for UIScrollView

调试视图层次结构中出现警告。但是,如果您想摆脱它,请在堆栈视图设置中添加一行:

    presentationStackView.snp.makeConstraints { (builder) in
        builder.top.equalTo(headerImageView.snp.bottom).inset(-Margins.xxLarge)
        builder.left.right.equalToSuperview()
        builder.bottom.equalTo(scrollView.snp.bottom)

        // add this line
        builder.height.equalTo(0).priority(250)

    }

这将为堆栈视图提供一个有效高度(零),以便自动布局在它为空时考虑...但是 250 的低优先级将允许它在您添加时垂直扩展排列的子视图。