简体   繁体   English

UIScrollView 未显示在 UIStackView 内

[英]UIScrollView not showing inside UIStackView

I have one UIStackView that stacks vertically two horizontal UIStackViews.我有一个 UIStackView 垂直堆叠两个水平 UIStackViews。 That worked just fine.那工作得很好。 But the first sub-UIStackView had too many elements so I decided to wrap it inside a scrollView.但是第一个子 UIStackView 元素太多,所以我决定将它包装在一个滚动视图中。 The problem is that when I do so, this first sub-view just disappears, as if the UIScrollView had a height of 0.问题是当我这样做时,第一个子视图就消失了,好像 UIScrollView 的高度为 0。

Here's the code:这是代码:

func initViews(){
    let containerStack = UIStackView()
    addSubview(containerStack)
    containerStack.axis = .vertical
    containerStack.distribution = .equalCentering
    containerStack.isLayoutMarginsRelativeArrangement = true
    containerStack.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    
    
    let scrollView = UIScrollView()
    let scrolledStack = UIStackView()
    containerStack.addArrangedSubview(scrollView)
    scrollView.addSubview(scrolledStack)
    scrolledStack.distribution = .fill
    scrolledStack.isLayoutMarginsRelativeArrangement = true
    scrolledStack.layoutMargins = UIEdgeInsets(top: 20, left: 30, bottom: 20, right: 30)
    
    scrolledStack.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    scrolledStack.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
    scrolledStack.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    scrolledStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    scrolledStack.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
    
    
    let otherStack = UIStackView()
    containerStack.addArrangedSubview(otherStack)
    otherStack.distribution = .equalCentering
    otherStack.isLayoutMarginsRelativeArrangement = true
    otherStack.layoutMargins = UIEdgeInsets(top: 20, left: 30, bottom: 0, right: 30)
    
    
    containerStack.translatesAutoresizingMaskIntoConstraints = false
    containerStack.topAnchor.constraint(equalTo: topAnchor).isActive = true
    containerStack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    containerStack.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    containerStack.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
    
    
    for number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]{
        let text = UITextView()
        text.font = UIFont.boldSystemFont(ofSize: 14)
        text.text = number
        text.isScrollEnabled = false
        text.backgroundColor = .clear
        
        scrolledStack.addArrangedSubview(text)
    }
    for number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]{
        let text = UITextView()
        text.font = UIFont.boldSystemFont(ofSize: 14)
        text.text = number
        text.isScrollEnabled = false
        text.backgroundColor = .clear
        
        otherStack.addArrangedSubview(text)
    }
}

otherStack behaves as expected, but scrollView and scrolledStack just don't appear. otherStack 的行为符合预期,但 scrollView 和 scrolledStack 只是没有出现。 If I remove the scrollView and just add scrolledStack to containerStack, both stacks appear as expected.如果我删除 scrollView 并将 scrolledStack 添加到 containerStack,两个堆栈都会按预期显示。

Many UI view elements - such as UIScrollView - have no intrinsic height.许多 UI 视图元素(例如UIScrollView )没有固有高度。

You are putting a scroll view in a vertical stack view, with your stack view set to:您将滚动视图放在垂直堆栈视图中,堆栈视图设置为:

containerStack.distribution = .equalCentering

The problem comes in because the stack view cannot center its arranged subviews if they have no height.问题出现是因为如果堆栈视图没有高度,则堆栈视图无法将其排列的子视图居中。

If you change your containerStack to:如果您将containerStack更改为:

containerStack.distribution = .fillEqually

You will see both of the arranged subviews.您将看到两个排列好的子视图。

If you don't want them to have equal heights, then you need to provide some height value... either with an explicit scrollView.heightAnchor.constraint(equalToConstant: 100.0).isActive = true or perhaps relative to the overall height.如果您不希望它们具有相等的高度,那么您需要提供一些高度值......或者使用明确的scrollView.heightAnchor.constraint(equalToConstant: 100.0).isActive = true或者可能相对于整体高度。


Edit - in response to comment...编辑- 回应评论......

Add these lines at the bottom of your initViews() func:initViews()函数的底部添加这些行:

scrolledStack.translatesAutoresizingMaskIntoConstraints = false

scrollView.backgroundColor = .red
scrolledStack.backgroundColor = .lightGray
otherStack.backgroundColor = .systemBlue
containerStack.backgroundColor = .systemGreen

and, instead of .clear , give your first set of text views:并且,而不是.clear ,给出你的第一组文本视图:

text.backgroundColor = .cyan

and your second set of text views:和您的第二组文本视图:

text.backgroundColor = .green

Here's how it looks now when I run your code:这是我现在运行您的代码时的样子:

在此处输入图像描述

That is probably not what you're going for, but by giving your views contrasting background colors, it makes it much easier to see what's going on.这可能不是您想要的,但是通过为您的视图提供对比背景颜色,可以轻松地查看正在发生的事情。

I readapted a bit your code and created this swift playground:我重新编写了一些您的代码并创建了这个快速的游乐场:

import UIKit
import PlaygroundSupport

final class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    let containerStack = UIStackView()
    view.addSubview(containerStack)
    containerStack.axis = .vertical
    containerStack.distribution = .equalCentering
    containerStack.translatesAutoresizingMaskIntoConstraints = false

    let scrollView = UIScrollView()
    let scrolledStack = UIStackView()
    scrolledStack.translatesAutoresizingMaskIntoConstraints = false
    containerStack.addArrangedSubview(scrollView)
    scrollView.addSubview(scrolledStack)

    NSLayoutConstraint.activate([
      scrolledStack.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
      scrolledStack.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
      scrolledStack.topAnchor.constraint(equalTo: scrollView.topAnchor),
      scrolledStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
      scrolledStack.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor)
    ])

    let otherStack = UIStackView()
    containerStack.addArrangedSubview(otherStack)
    otherStack.distribution = .equalCentering
    otherStack.isLayoutMarginsRelativeArrangement = true
    otherStack.layoutMargins = UIEdgeInsets(top: 20, left: 30, bottom: 0, right: 30)

    NSLayoutConstraint.activate([
      containerStack.topAnchor.constraint(equalTo: view.topAnchor),
      containerStack.bottomAnchor.constraint(equalTo: view.bottomAnchor),
      containerStack.leftAnchor.constraint(equalTo: view.leftAnchor),
      containerStack.rightAnchor.constraint(equalTo: view.rightAnchor),
    ])

    for number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]{
      let text = UILabel()
      text.font = UIFont.boldSystemFont(ofSize: 14)
      text.text = number

      scrolledStack.addArrangedSubview(text)
      NSLayoutConstraint.activate([
        text.widthAnchor.constraint(equalToConstant: 100)
      ])
    }
    for number in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]{
      let text = UILabel()
      text.font = UIFont.boldSystemFont(ofSize: 14)
      text.text = number

      otherStack.addArrangedSubview(text)
    }

  }
}

PlaygroundPage.current.liveView = ViewController()
PlaygroundPage.current.needsIndefiniteExecution = true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM