简体   繁体   English

用多个子视图调整ScrollView

[英]Adjust ScrollView with multiple SubViews

I have to dynamically create some UILabel and UITextViews according to some Data ~ around 20 - all of them with dynamic height/lines of Text for an IOS App in Swift. 我必须根据一些数据〜20左右动态创建一些UILabel和UITextViews-它们都具有Swift中IOS App的动态高度/文本行。

Since the screen is not large enough I am adding the Views to a ScrollView, but unfortunately the contentsize property of my ScrollView seems not to receive the proper values. 由于屏幕不够大,所以我将视图添加到ScrollView中,但是不幸的是,我的ScrollView的contentsize属性似乎没有收到正确的值。

I'm debugging since a couple of hours and tried different set ups but so far none of them worked out. 几个小时以来,我一直在调试,并尝试了不同的设置,但到目前为止,它们都没有解决。

The sizing is done in a custom method refreshUI() which gets firstly called in viewDidLoad(). 大小调整是在自定义方法refreshUI()中完成的,该方法首先在viewDidLoad()中调用。 The ViewController simply contains one centred Heading Label and the ScrollView which fills the rest of the space (pinned to Top, Left, Right, Bottom with 8.0). ViewController只是包含一个居中的标题标签和ScrollView,它填充了其余的空间(固定为8.0的Top,Left,Right,Bottom)。 Then I'm trying to populate my Data in that scrollView as follows: 然后,我尝试按照以下方式在该scrollView中填充数据:

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")
}

The ScrollView is not vertically scrollable, although some content is not displayed due to being out of the screen. ScrollView不能垂直滚动,尽管某些内容由于不在屏幕上而无法显示。 But it scrolls horizontally, although I'm setting the width of each view to the width of the SCrollView, which should mean that every SubView is just as big as the size of the ScrollView and thus not vertically scrollable. 但是它是水平滚动的,尽管我将每个视图的宽度设置为SCrollView的宽度,这应该意味着每个SubView都和ScrollView的大小一样大,因此不能垂直滚动。

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

When you run refreshUI() inside of viewDidLoad() , the subviews that are being created are using the Interface Builder defaults for the parent views instead of the actual sizes on the device. 当您运行refreshUI()viewDidLoad()正在使用父视图,而不是设备的实际尺寸的界面生成器默认创建的子视图。 This is likely why your sizes are not what you expect. 这可能就是为什么您的尺寸不符合您的期望。 If you run refreshUI() inside of viewDidLayoutSubviews() instead, then the subviews will correctly read the widths and heights of the parent view. 如果refreshUI()viewDidLayoutSubviews() refreshUI()内部运行refreshUI() ,则子视图将正确读取父视图的宽度和高度。

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

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