Search code examples
iosswiftuiscrollview

Filling a UIScrollView with content programmatically


There has to be a better way to fill a UIScrollView with UILabel, and UIImageView and other content without having to define CGRectMake with a start position. Is there such a thing as a stacking view? Im assuming not really, but what is the proper way of adding content dynamically.

Heres what Im doing currently:

func configureView() {
    self.addHeaderImage()

    var scrollView: UIScrollView!
    var missionStatement: UILabel!
    var missionStatementText: UILabel!
    var history: UILabel!
    var historyText: UILabel!

    scrollView = UIScrollView()
    scrollView!.frame = CGRectMake(0, headerImage.bounds.height, self.view.bounds.width, self.view.bounds.height)
    scrollView!.contentSize = CGSize(width: self.view.bounds.width, height: self.view.bounds.height * 2)
    scrollView!.autoresizingMask = UIViewAutoresizing.FlexibleHeight
    self.view.addSubview(scrollView)

    missionStatement = UILabel()
    missionStatement!.frame = CGRectMake(10, 5, headerImage.bounds.width - 20, 30)
    missionStatement!.text = "Our Mission Statement"
    missionStatement!.font = UIFont(name: "HelveticaNeue-Bold", size: 22.0)
    scrollView.addSubview(missionStatement)

    missionStatementText = UILabel()
    missionStatementText!.frame = CGRectMake(10, missionStatement.frame.height, headerImage.bounds.width - 20, 100)
    missionStatementText!.text = "Covenant United Methodist Church, as a companionate community, serves people through the sharing, caring, and reaching out in the name of Jesus Christ."
    missionStatementText!.font = UIFont(name: "HelveticaNeue", size: 17.0)
    missionStatementText!.numberOfLines = 0
    scrollView.addSubview(missionStatementText)

    history = UILabel()
    // By the time Im done adding things to this 1 view, Its going to be an insane addition problem to find the starting y of the rectangle
    history!.frame = CGRectMake(0, missionStatement.frame.height, 0, 0)
}

Solution

  • You can write an extension to UIView

    extension UIView {
    
        func addSubviewAtBottomOfAllSubviews(view:UIView){
            var maxY = CGFloat(0)
            for subview in self.subviews{
                if maxY < subview.frame.maxY{
                    maxY = subview.frame.maxY
                }
            }
    
            view.frame.origin.y = maxY
            self.addSubview(view)
        }
    }
    

    And also write func to resize Scroll content view, so make it scrollable if the views highet is bigger than the scroll view

    extension UIScrollView{
        func resizeContentSize(){
    
            var contentRect = CGRectZero;
            for view in self.subviews{
                contentRect = CGRectUnion(contentRect, (view ).frame);
            }
    
            self.contentSize = contentRect.size;
    
        }
    }
    

    use:

    scrollView.addSubviewAtBottomOfAllSubviews(textLabel)
    scrollView.addSubviewAtBottomOfAllSubviews(anotherView)
    scrollView.resizeContentSize()