简体   繁体   English

ScrollView不滚动与子视图

[英]ScrollView not scrolling with subviews

I couldn't get my UIScrollView to scroll. 我无法滚动UIScrollView Here is my code: 这是我的代码:

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {

    var scrollView = UIScrollView()


    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView = UIScrollView(frame : CGRect ( x:0,y:0,width:UIScreen.main.bounds.width,height:UIScreen.main.bounds.height))
        scrollview.delegate = self
        view.addSubview(scrollView)

        for i in 0...14 {
            let numLabel = UILabel(frame : CGRect( x : 0 , y : 10+(i*40) , width : UIScreen.main.bounds.width - 20 : height : 40))
            numlabel.text = "\(i)"
            scrollView.addSubview(numLabel)
        }

    }

}

This is making the views appear but not scrolling. 这使视图出现但不滚动。

Scroll view scrolls to its content size. 滚动视图滚动到其内容大小。 Whenever you add a subview to scroll view you should make sure that your scroll view's content size is enough to fit the new view. 每当将子视图添加到滚动视图时,都应确保滚动视图的内容大小足以容纳新视图。 In your case you are not taking care of that. 在您的情况下,您不会在意。 Ideally whenever you add a subview you should correspondingly adjust the hight of the scroll view content size. 理想情况下,无论何时添加子视图,都应相应地调整滚动视图内容大小的高度。 In your case after you have added all of the labels to scroll view ie after for loop add following line 在您的情况下,将所有标签添加到滚动视图后,即在for循环后添加以下行

self.scrollView.contentSize = CGSize(width:self.scrollView.bounds.size.width,height:10+(15‌​*40))

or in the for loop after adding label you can do the following 或者在添加标签后的for循环中,您可以执行以下操作

self.scrollView.contentSize = CGSize(width:self.scrollView.bounds.size.width,height:10+((i+1)*40))

The second approach is better. 第二种方法更好。 Because if you add more labels to scroll view it will take care of that. 因为如果您添加更多标签来滚动视图,它将解决此问题。 Again, make it a rule of thumb, whenever adding a view to scroll view make sure that its content size is updated to fit all the subviews. 同样,将其作为经验法则,每当向滚动视图添加视图时,请确保其内容大小已更新为适合所有子视图。

While you can manually set the contentSize , I would not advise doing that. 虽然您可以手动设置contentSize ,但我不建议您这样做。

Instead, I'd use constraints for the subviews of the scroll view. 相反,我将约束用于滚动视图的子视图。 The auto-layout engine will calculate the contentSize for you automatically. 自动布局引擎将自动为您计算contentSize It will also take care of adjusting everything if the device rotates. 如果设备旋转,它还将负责调整所有内容。

I'd also suggest using a stack view, you don't have to mess around with either manual frames for the labels nor with constraints between them. 我还建议您使用堆栈视图,而不必麻烦标签的手动框架或标签之间的约束。

So, you can do something like: 因此,您可以执行以下操作:

var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)

    let stackView = UIStackView()
    stackView.axis = .vertical
    stackView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(stackView)

    for i in 0 ... 140 {
        let numLabel = UILabel()
        numLabel.translatesAutoresizingMaskIntoConstraints = false
        numLabel.text = "\(i)"
        numLabel.font = .preferredFont(forTextStyle: .body)
        stackView.addArrangedSubview(numLabel)
    }

    NSLayoutConstraint.activate([
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        scrollView.topAnchor.constraint(equalTo: view.topAnchor),
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),

        stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
        stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
        stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
        stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
    ])
}

Note the use of UIFont.preferredFont(forTextStyle: .body) to enjoy Dynamic Text. 注意使用UIFont.preferredFont(forTextStyle: .body)来欣赏动态文本。 This means that if the user has a larger font specified in their settings, this will automatically show the larger font in this app. 这意味着,如果用户在其设置中指定了较大的字体,它将自动在此应用程序中显示较大的字体。 But more importantly, we didn't have to calculate the size of the label for that font. 但更重要的是,我们不必为该字体计算标签的大小。 Constraints and the stack view took care of both the frames of the labels as well as the scroll view's contentSize . 约束和堆栈视图负责标签的框架以及滚动视图的contentSize


For the sake of completeness, it's worth noting that the alternative is to use a UITableView or UICollectionView . 为了完整起见,值得注意的是,替代方法是使用UITableViewUICollectionView This is a scalable, memory efficient way of viewing data within a scroll view. 这是在滚动视图中查看数据的可伸缩,内存高效的方式。 It's beyond the scope of this question, but it's worth remembering as you consider creating large scroll views. 这超出了此问题的范围,但是当您考虑创建大型滚动视图时,值得记住。

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

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