首页 > 解决方案 > 尝试以编程方式设置 Dynamic UIScrollView 但遇到问题

问题描述

最近我尝试根据这个网站设置一个动态 UIScrollView:https ://medium.com/@javedmultani16/uiscrollview-dynamic-content-size-through-storyboard-in-ios-fb873e9278e

我试图一步一步地做,但似乎我误解了一些东西,但我无法弄清楚。这是我的代码,我尝试添加 30 UITextField 并将 UIScrollView 设置为与这些内容相等的高度。

我遇到的问题,滚动视图不能正常工作,它只能滚动一点,就像我只能滚动到大约 8 或 9 行,下面的其他我不能向下滚动。

    override func viewDidLoad() {
    super.viewDidLoad()
    
    //Step 1
    let scrollview = UIScrollView()
    view.addSubview(scrollview)
    scrollview.translatesAutoresizingMaskIntoConstraints = false
    scrollview.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollview.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    scrollview.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollview.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollview.alwaysBounceVertical = true
    
    //Step 2
    let oneview = UIView()
    scrollview.addSubview(oneview)
    oneview.translatesAutoresizingMaskIntoConstraints = false
    oneview.topAnchor.constraint(equalTo: scrollview.topAnchor).isActive = true
    oneview.bottomAnchor.constraint(equalTo: scrollview.bottomAnchor).isActive = true
    oneview.leadingAnchor.constraint(equalTo: scrollview.leadingAnchor).isActive = true
    oneview.trailingAnchor.constraint(equalTo: scrollview.trailingAnchor).isActive = true
    oneview.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    let heightConstraint = oneview.heightAnchor.constraint(equalTo: view.heightAnchor)
    heightConstraint.isActive = true
    heightConstraint.priority = .defaultLow
    
    //Step 3
    for i in 1...30{
        let field = UITextField()
        field.placeholder = "This is line "+String(i+1)
        field.backgroundColor = .gray
        field.isUserInteractionEnabled = false
        oneview.addSubview(field)
        field.translatesAutoresizingMaskIntoConstraints = false
        field.widthAnchor.constraint(equalTo: oneview.widthAnchor, multiplier: 0.8).isActive = true
        field.heightAnchor.constraint(equalToConstant: 50).isActive = true
        field.centerXAnchor.constraint(equalTo: oneview.centerXAnchor).isActive = true
        field.topAnchor.constraint(equalTo: oneview.topAnchor, constant: CGFloat(100*i)).isActive = true
    }
}

标签: iosswiftxcode

解决方案


使用这个虚拟子视图(oneview在您的代码中)的全部意义在于它的内容可以告诉虚拟子视图它应该是什么高度,并且滚动视图的内容大小将适合该高度。

但是,您的文本字段的约束不建议oneview!. 所有文本字段的约束都说是文本字段

  • 应该在顶部下方一些距离oneview
  • 应该有一定的高度
  • 应该有相同的中心 Xoneview
  • 应该有相同的宽度oneview

为了满足上述要求,oneview' 的高度根本不需要改变。布局引擎可以将您的文本字段放在 的边界之外oneview,并且仍然满足上述约束。(考虑一下!)

但是,如果您在最后一个文本字段中再添加一个约束,它

应该在底部上方一定距离oneview

然后oneview必须调整大小以满足该要求。你是在间接暗示一个高度oneview,因为你在说

对于最后一个文本字段,我希望它上面有这么多空间,下面有这么多空间。

我们也可以将“一定距离”设为零。以下是您将如何在代码中执行此操作:

// in the loop...
if i == 30 {
    field.bottomAnchor.constraint(equalTo: oneview.bottomAnchor).isActive = true
}

判断其高度的更好方法oneview是使用UIStackView. 将步骤 2 和 3 替换为:

    let oneview = UIStackView()
    oneview.alignment = .fill
    oneview.distribution = .equalSpacing
    oneview.spacing = 50
    oneview.axis = .vertical
    scrollview.addSubview(oneview)
    oneview.translatesAutoresizingMaskIntoConstraints = false
    oneview.topAnchor.constraint(equalTo: scrollview.topAnchor).isActive = true
    oneview.bottomAnchor.constraint(equalTo: scrollview.bottomAnchor).isActive = true
    oneview.leadingAnchor.constraint(equalTo: scrollview.leadingAnchor).isActive = true
    oneview.trailingAnchor.constraint(equalTo: scrollview.trailingAnchor).isActive = true
    oneview.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    let heightConstraint = oneview.heightAnchor.constraint(equalTo: view.heightAnchor, constant: 25)
    heightConstraint.isActive = true
    heightConstraint.priority = .defaultLow
    
    for i in 1...30{
        let field = UITextField()
        field.placeholder = "This is line "+String(i+1)
        field.backgroundColor = .gray
        field.isUserInteractionEnabled = false
        oneview.addArrangedSubview(field)
        field.translatesAutoresizingMaskIntoConstraints = false
        field.heightAnchor.constraint(equalToConstant: 50).isActive = true
    }

推荐阅读