使用多个 SubView 调整 ScrollView

Posted

技术标签:

【中文标题】使用多个 SubView 调整 ScrollView【英文标题】:Adjust ScrollView with multiple SubViews 【发布时间】:2015-10-13 05:43:13 【问题描述】:

我必须根据一些数据动态创建一些 UILabel 和 UITextViews ~ 大约 20 - 它们都具有 Swift 中 ios 应用程序的动态高度/文本行。

由于屏幕不够大,我将视图添加到 ScrollView,但不幸的是,我的 ScrollView 的 contentsize 属性似乎没有收到正确的值。

我已经调试了几个小时并尝试了不同的设置,但到目前为止都没有成功。

大小是在一个自定义方法 refreshUI() 中完成的,该方法首先在 viewDidLoad() 中调用。 ViewController 只包含一个居中的标题标签和填充其余空间的 ScrollView(使用 8.0 固定到 Top、Left、Right、Bottom)。 然后我尝试在该滚动视图中填充我的数据,如下所示:

func refreshUI()
    println("refreshUI()")

    questionnaireTitle.text = site.questionnaireName
    let questionnaire = site.questionnaire

    //removes all SubViews in ScrollView
    clearView(scrollView)
    scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)


    for questionGroup in questionnaire

        //QUESTIONGROUP HEADING
        let questionGroupHeading = UILabel()
        questionGroupHeading.setTranslatesAutoresizingMaskIntoConstraints(false)
        questionGroupHeading.text = questionGroup.questionsHeading
        questionGroupHeading.sizeToFit()
        scrollView.addSubview(questionGroupHeading)
        viewStack.append(questionGroupHeading)


        //QUESTION
        for question in questionGroup.questions
            //QUESTION LABEL
            let questionLabel = UILabel()
            questionLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
            questionLabel.text = question.text
            questionLabel.numberOfLines = 0
            questionLabel.lineBreakMode = .ByWordWrapping
            questionLabel.sizeToFit()
            scrollView.addSubview(questionLabel)
            viewStack.append(questionLabel)

            if question.type == "selector"
                //SELECTOR QUESTION
                println("selector Question")

                for statement in question.statements
                    //TODO add Statement + Picker
                
            
            else if question.type == "standard"
                //STANDARD QUESTION
                println("standard question")
                let answerLabel = UITextField()
                answerLabel.placeholder = "here goes your answer"
                answerLabel.sizeToFit()
                answerLabel.backgroundColor = UIColor.whiteColor()
                answerLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
                scrollView.addSubview(answerLabel)
                viewStack.append(answerLabel)
            
        


    

    //setUpConstraints

    var counter = 0
    var height:CGFloat = 0.0
    for view in viewStack
        let rightConst = NSLayoutConstraint(item: view, attribute: .Right, relatedBy: .Equal, toItem: scrollView, attribute: .Right, multiplier: 1.0, constant: 0.0)
        let leftConst = NSLayoutConstraint(item: view, attribute: .Left, relatedBy: .Equal, toItem: scrollView, attribute: .Left, multiplier: 1.0, constant: 0.0)
        let widthConst = NSLayoutConstraint(item: view, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: scrollView.frame.width)
        view.addConstraint(widthConst)
        scrollView.addConstraint(leftConst)
        scrollView.addConstraint(rightConst)

        //pin first view to top of scrollView
        if counter == 0
            let topConst = NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Top, multiplier: 1.0, constant: 0.0)
            scrollView.addConstraint(topConst)
        
        //pin all other views to the top of the previousView
        else
            let topConst = NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal, toItem: viewStack[counter - 1], attribute: .Bottom, multiplier: 1.0, constant: 8.0)
            scrollView.addConstraint(topConst)
        
        counter++

        height += view.bounds.height
    


    let contentSize = CGSize(width: scrollView.frame.width, height: height)
    scrollView.contentSize = contentSize
    scrollView.contentOffset = CGPoint(x: 0, y: 0)

    println("refreshUI() done")

ScrollView 不可垂直滚动,虽然有些内容由于超出屏幕而无法显示。 但它水平滚动,虽然我将每个视图的宽度设置为 SCrollView 的宽度,这应该意味着每个子视图都与 ScrollView 的大小一样大,因此不能垂直滚动。

【问题讨论】:

【参考方案1】:

如果您使用的是 AutoLayout,那么 this 教程将有助于实现滚动视图。

【讨论】:

【参考方案2】:

当您在viewDidLoad() 内运行refreshUI() 时,正在创建的子视图将使用父视图的Interface Builder 默认值,而不是设备上的实际大小。这可能就是为什么您的尺寸不是您所期望的。如果您在 viewDidLayoutSubviews() 内运行 refreshUI(),则子视图将正确读取父视图的宽度和高度。

【讨论】:

以上是关于使用多个 SubView 调整 ScrollView的主要内容,如果未能解决你的问题,请参考以下文章

ContentViews Subview 在 UIScrollView iOS 中没有动态改变高度

addArrangedSubview 没有动画

java 来自http://stackoverflow.com/questions/4628800/android-how-to-check-if-a-view-inside-of-scrollvie

何时使用 f:view 和 f:subview

如何使用 UISilder 在 SubView 中添加和删除 UIButtons?

UIView 中的自动替换子视图