a2b123
a2b123

Reputation: 583

Using ScrollView Programmatically in Swift 3

I have searched other questions and seem to still have some trouble creating my scrollView programmatically with autolayout in swift 3. I am able to get my scrollview to show up as shown in the picture below, but when I scroll to the bottom my other label does not show up and the 'scroll top' label does not disappear.

ScrollView

Hoping someone can help review my code below!

import UIKit

class ViewController: UIViewController {

let labelOne: UILabel = {
    let label = UILabel()
    label.text = "Scroll Top"
    label.backgroundColor = .red
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

let labelTwo: UILabel = {
    let label = UILabel()
    label.text = "Scroll Bottom"
    label.backgroundColor = .green
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()


override func viewDidLoad() {
    super.viewDidLoad()

    let screensize: CGRect = UIScreen.main.bounds
    let screenWidth = screensize.width
    let screenHeight = screensize.height
    var scrollView: UIScrollView!
    scrollView = UIScrollView(frame: CGRect(x: 0, y: 120, width: screenWidth, height: screenHeight))
    scrollView.contentSize = CGSize(width: screenWidth, height: 2000)
    scrollView.addSubview(labelOne)
    scrollView.addSubview(labelTwo)


    view.addSubview(labelOne)
    view.addSubview(labelTwo)
    view.addSubview(scrollView)

    // Visual Format Constraints
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": labelOne]))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-100-[v0]", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": labelOne]))

    // Using iOS 9 Constraints in order to place the label past the iPhone 7 view
    view.addConstraint(NSLayoutConstraint(item: labelTwo, attribute: .top, relatedBy: .equal, toItem: labelOne, attribute: .bottom, multiplier: 1, constant: screenHeight + 200))
    view.addConstraint(NSLayoutConstraint(item: labelTwo, attribute: .right, relatedBy: .equal, toItem: labelOne, attribute: .right, multiplier: 1, constant: 0))
    view.addConstraint(NSLayoutConstraint(item: labelTwo, attribute: .left, relatedBy: .equal, toItem: labelOne, attribute: .left, multiplier: 1, constant: 0)     

    }

}

Upvotes: 30

Views: 87195

Answers (7)

Dmitry
Dmitry

Reputation: 2168

Here is my approach with UIStackView as a container for UIScrollView (in my opinion it's more flexible than provided answers) :

class ViewController: UIViewController {
    private let scrollView : UIScrollView = {
        let view = UIScrollView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.showsHorizontalScrollIndicator = false
        view.showsVerticalScrollIndicator = false
        view.backgroundColor = .black
        return view
    }()

    private lazy var scrollViewContainer: UIStackView = {
        let view = UIStackView()
        view.axis = .vertical
        view.spacing = 0
        view.distribution = .fill
        view.alignment = .fill
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    private lazy var redView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .red
        return view
    }()
    
    private lazy var whiteView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .white
        return view
    }()

    private lazy var blueView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .blue
        return view
    }()

    private func setupSubViews() {
        scrollViewContainer.addArrangedSubview(whiteView)
        scrollViewContainer.addArrangedSubview(blueView)
        scrollViewContainer.addArrangedSubview(redView)
        
        let itemHeight: CGFloat = 100
        
        let constraints = [
            whiteView.heightAnchor.constraint(equalToConstant: itemHeight),
            blueView.heightAnchor.constraint(equalToConstant: itemHeight),
            redView.heightAnchor.constraint(equalToConstant: itemHeight)
        ]
        
        NSLayoutConstraint.activate(constraints)
    }

    private func setupScrollView()
    {
        view.addSubview(scrollView)
        
        scrollView.addSubview(scrollViewContainer)

        let safeArea = view.safeAreaLayoutGuide
        
        let constraints = [
            scrollView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor),
            scrollView.topAnchor.constraint(equalTo: safeArea.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor),

            scrollViewContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            scrollViewContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            scrollViewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor),
            scrollViewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            scrollViewContainer.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
        ]
        
        NSLayoutConstraint.activate(constraints)
    }
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupScrollView()
        setupSubViews()
    }
}

Upvotes: 0

DonMag
DonMag

Reputation: 77690

It is easy to use constraints to define the scroll content size - so you don't have to do any manual calculations.

Just remember:

  1. The content elements of your scroll view must have left / top / width / height values. In the case of objects such as labels, they have intrinsic sizes, so you only have to define the left & top.
  2. The content elements of your scroll view also define the bounds of the scrollable area - the contentSize - but they do so with the bottom & right constraints.
  3. Combining those two concepts, you see that you need a "continuous chain" with at least one element defining the top / left / bottom / right extents.

Here is a simple example, that will run directly in a Playground page:

import UIKit
import PlaygroundSupport

class TestViewController : UIViewController {

    let labelOne: UILabel = {
        let label = UILabel()
        label.text = "Scroll Top"
        label.backgroundColor = .red
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let labelTwo: UILabel = {
        let label = UILabel()
        label.text = "Scroll Bottom"
        label.backgroundColor = .green
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // add the scroll view to self.view
        self.view.addSubview(scrollView)
        
        // constrain the scroll view to 8-pts on each side
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
        
        // add labelOne to the scroll view
        scrollView.addSubview(labelOne)
        
        // constrain labelOne to left & top with 16-pts padding
        // this also defines the left & top of the scroll content
        labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
        labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true
        
        // add labelTwo to the scroll view
        scrollView.addSubview(labelTwo)
        
        // constrain labelTwo at 400-pts from the left
        labelTwo.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 400.0).isActive = true

        // constrain labelTwo at 1000-pts from the top
        labelTwo.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 1000).isActive = true
        
        // constrain labelTwo to right & bottom with 16-pts padding
        labelTwo.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -16.0).isActive = true
        labelTwo.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -16.0).isActive = true
        
    }
    
}


let vc = TestViewController()
vc.view.backgroundColor = .yellow
PlaygroundPage.current.liveView = vc

Edit - since this answer still gets occasional attention, I've updated the code to use more modern syntax, to respect the safe-area, and to use the scroll view's .contentLayoutGuide:

class TestViewController : UIViewController {
    
    let labelOne: UILabel = {
        let label = UILabel()
        label.text = "Scroll Top"
        label.backgroundColor = .yellow
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let labelTwo: UILabel = {
        let label = UILabel()
        label.text = "Scroll Bottom"
        label.backgroundColor = .green
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // add the scroll view to self.view
        self.view.addSubview(scrollView)

        // add labelOne to the scroll view
        scrollView.addSubview(labelOne)
        
        // add labelTwo to the scroll view
        scrollView.addSubview(labelTwo)
        
        // always a good idea to respect safe area
        let safeG = view.safeAreaLayoutGuide
        
        // we want to constrain subviews to the scroll view's Content Layout Guide
        let contentG = scrollView.contentLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // constrain the scroll view to safe area with 8-pts on each side
            scrollView.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 8.0),
            scrollView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor, constant: 8.0),
            scrollView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor, constant: -8.0),
            scrollView.bottomAnchor.constraint(equalTo: safeG.bottomAnchor, constant: -8.0),
            
            // constrain labelOne to leading & top of Content Layout Guide with 16-pts padding
            // this also defines the left & top of the scroll content
            labelOne.topAnchor.constraint(equalTo: contentG.topAnchor, constant: 16.0),
            labelOne.leadingAnchor.constraint(equalTo: contentG.leadingAnchor, constant: 16.0),

            // constrain labelTwo leading at 400-pts from labelOne trailing
            labelTwo.leadingAnchor.constraint(equalTo: labelOne.trailingAnchor, constant: 400.0),
            
            // constrain labelTwo top at 1000-pts from the labelOne bottom
            labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor, constant: 1000),
            
            // constrain labelTwo to trailing & bottom of Content Layout Guide with 16-pts padding
            // this also defines the right & bottom of the scroll content
            labelTwo.trailingAnchor.constraint(equalTo: contentG.trailingAnchor, constant: -16.0),
            labelTwo.bottomAnchor.constraint(equalTo: contentG.bottomAnchor, constant: -16.0),
            
        ])
        
    }
    
}

Upvotes: 69

SuryaKantSharma
SuryaKantSharma

Reputation: 1183

For me this work like charm

class WithDrawConfirmationViewController: UIViewController, WithDrawConfirmationViewProtocol {

    var presenter: WithDrawConfirmationPresenterProtocol?
    private let viewbackgroundColor = UIColor(hexString: "#F5F5F8")
    // MARK:- View properties
    lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        //view.backgroundColor = .red
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()
    
    lazy var contentView: UIView = {
        let view = UIView()
        //view.backgroundColor = .green
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    lazy var headerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    private lazy var titleLabel:UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor.themeBlack
        label.text = "Withdraw Confirmation"//"Loading.."
        label.textAlignment = .center
        label.font = UIFont(name: "AvenirNext-DemiBold", size: 20)
        label.numberOfLines = 0
        label.lineBreakMode = .byWordWrapping
        return label
    }()
    
    
    private lazy var descriptionLabel:UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor.themeGray
        label.text = "Please confirm your fixed deposit details before withdrawing your deposit"// "Loading.."
        label.textAlignment = .center
        label.font = UIFont(name: "AvenirNext-Medium", size: 14)
        label.numberOfLines = 0
        label.lineBreakMode = .byWordWrapping
        label.setContentHuggingPriority(1000, for: .vertical)
        return label
    }()
    
    private lazy var instructionLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor.themeGray
        label.text = "Complete fixed deposit will be withdrawn and the money will be debited to your account within 1-2 working days."//"Loading.."
        label.textAlignment = .left
        label.font = UIFont(name: "AvenirNext-Medium", size: 14)
        label.numberOfLines = 0
        label.lineBreakMode = .byWordWrapping
        return label
    }()
    
    private lazy var warningLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor.themeBlue
        label.text = "Axis bank will levy a penalty of 1% - 2% for premature withdrawal"//"Loading.."
        label.textAlignment = .left
        label.font = UIFont(name: "AvenirNext-DemiBold", size: 13)
        label.numberOfLines = 0
        label.lineBreakMode = .byWordWrapping
        return label
    }()
    
    private lazy var warningView: UIView = {
        let view = UIView()
        view.cornerradius = 5
        view.backgroundColor = UIColor(hexFromString: "#E8F4FD")
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    private lazy var fdInformationDetailView: FDPurchaseDetailView = {
        let view = FDPurchaseDetailView(isPoweredByViewVisible: false)
        //view.backgroundColor = .red
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    private lazy var footerCTAView: FooterButtonViewView = {
        let view = FooterButtonViewView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    // MARK:- Life cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        contentView.backgroundColor = viewbackgroundColor
        scrollView.backgroundColor = viewbackgroundColor
        setUpUI()
        presenter?.viewDidLoadTriggered()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    }
    
    private func setUpUI() {
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        view.backgroundColor = viewbackgroundColor
        addFooter()
        setUpHeaderView()
        setUpFDDetailView()
        setUpInformationAndWarningView()
        //scrollView.backgroundColor = .lightGray
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: footerCTAView.topAnchor).isActive = true
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 100, right: 0)
        
        contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
        contentView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
        //contentView.bottomAnchor.constraint(equalTo: footerCTAView.topAnchor).isActive = true
    }
    
    private func setUpHeaderView() {
        contentView.addSubview(headerView)
        headerView.addSubviews([titleLabel, descriptionLabel])
        
        headerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
        headerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true
        headerView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 4).isActive = true
       
        titleLabel.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 8).isActive = true
        titleLabel.trailingAnchor.constraint(equalTo: headerView.trailingAnchor).isActive = true
        titleLabel.topAnchor.constraint(equalTo: headerView.topAnchor, constant: 8).isActive = true
        
        descriptionLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant:  20).isActive = true
        descriptionLabel.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 8).isActive = true
        descriptionLabel.trailingAnchor.constraint(equalTo: headerView.trailingAnchor).isActive = true
        descriptionLabel.bottomAnchor.constraint(equalTo: headerView.bottomAnchor, constant: -20).isActive = true
    }
    
    
    private func setUpFDDetailView() {
        contentView.addSubview(fdInformationDetailView)
        fdInformationDetailView.topAnchor.constraint(equalTo: headerView.bottomAnchor).isActive = true
        fdInformationDetailView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
        fdInformationDetailView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true
       
    }
    
    private func setUpInformationAndWarningView() {
        contentView.addSubview(instructionLabel)
        
        instructionLabel.topAnchor.constraint(equalTo: fdInformationDetailView.bottomAnchor, constant: 20).isActive = true
        instructionLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
        instructionLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true
        
        warningView.addSubview(warningLabel)
        warningLabel.topAnchor.constraint(equalTo: warningView.topAnchor, constant: 8).isActive = true
        warningLabel.leadingAnchor.constraint(equalTo: warningView.leadingAnchor, constant: 20).isActive = true
        warningLabel.trailingAnchor.constraint(equalTo: warningView.trailingAnchor, constant: -20).isActive = true
        warningLabel.bottomAnchor.constraint(equalTo: warningView.bottomAnchor, constant: -8).isActive = true
        
        contentView.addSubview(warningView)
        
        warningView.topAnchor.constraint(equalTo: instructionLabel.bottomAnchor, constant: 8).isActive = true
        warningView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
        warningView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true
       //warningView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        warningView.bottomAnchor.constraint(greaterThanOrEqualTo: contentView.bottomAnchor, constant: -20).isActive = true
        
    }
    
    private func addFooter() {
        view.addSubview(footerCTAView)
        footerCTAView.delegate = self
        footerCTAView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        footerCTAView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        footerCTAView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
    }
}

Upvotes: 2

Rishabh Shukla
Rishabh Shukla

Reputation: 501

Copy and paste this controller in your project

class BaseScrollViewController: UIViewController {

lazy var contentViewSize = CGSize(width: self.view.frame.width, height: self.view.frame.height + 100)
lazy var scrollView: UIScrollView = {
    let view = UIScrollView(frame: .zero)
    view.backgroundColor = .white
    view.frame = self.view.bounds
    view.contentSize = contentViewSize
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()
lazy var containerView: UIView = {
    let v = UIView()
    v.backgroundColor = .white
    v.frame.size = contentViewSize
    return v
}()

override func viewDidLoad() {
    view.backgroundColor = .white
    view.addSubview(scrollView)
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    scrollView.addSubview(containerView)
    setupContainer(containerView)
    super.viewDidLoad()
    
}

public func setupContainer(_ container: UIView) {
    
}

}

Usage for above code:

class ClientViewController: BaseScrollViewController {
override func viewDidLoad() {
    super.viewDidLoad()
    // do your stuff here
}

override func setupContainer(_ container: UIView) {
    // add views here
}

}

Upvotes: 0

user845978
user845978

Reputation: 257

These answers do not work with large titles in the navigation bar. Make sure you have the code below in your viewDidLoad() method of your view controller:

self.navigationController?.navigationBar.prefersLargeTitles = false

Upvotes: -9

Nandhu
Nandhu

Reputation: 11

Set scrollview images to the wallpaper:

@IBOutlet var scroll_view_img: UIScrollView!

var itemPhotoList = NSMutableArray()

var button = NSMutableArray()    

@IBOutlet var imageview_big: UIImageView!

override func viewDidLoad() {

    super.viewDidLoad()
    itemPhotoList = ["grief-and-loss copy.jpg","aaa.jpg","image_4.jpeg"]        

    // button = ["btn1","btn2"]

    let width:CGFloat = 100
    let height:CGFloat = 100
    var xposition:CGFloat = 10
    var scroll_contont:CGFloat = 0

    for i in 0 ..< itemPhotoList.count
    {
        var button_img = UIButton()
        button_img = UIButton(frame: CGRect(x: xposition, y: 50, width: width, height: height))
        let img = UIImage(named:itemPhotoList[i] as! String)
        button_img.setImage(img, for: .normal)
        scroll_view_img.addSubview(button_img)
        button_img.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        button_img.tag = i
        view.addSubview(scroll_view_img)
        xposition += width+10
        scroll_contont += width
        scroll_view_img.contentSize = CGSize(width: scroll_contont, height: height)
    }
}

func buttonAction(sender: UIButton!)
{
    switch sender.tag {
    case 0:
        imageview_big.image = UIImage(named: "grief-and-loss copy.jpg")
    case 1:
        imageview_big.image = UIImage(named: "aaa.jpg")
    case 2:
        imageview_big.image = UIImage(named: "image_4.jpeg")
    default:
        break
    }
}

Upvotes: 0

Fangming
Fangming

Reputation: 25280

Two things.

1. Add the labels to scroll view, not your view

You want your label to scroll with scroll view, then you should not add it on your view. When running your code, you can scroll but the fixed label there is pinned to your view, not on your scroll view

2. Make sure you added your constraints correctly

Try it on your storyboard about what combination of constraint is enough for a view. At least 4 constraints are needed for a label.

Bottom line

Here is a modified version of your code. For constraint I added padding left, padding top, width and height and it works. My code is

let labelOne: UILabel = {
    let label = UILabel()
    label.text = "Scroll Top"
    label.backgroundColor = .red
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

let labelTwo: UILabel = {
    let label = UILabel()
    label.text = "Scroll Bottom"
    label.backgroundColor = .green
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()


override func viewDidLoad() {
    super.viewDidLoad()

    let screensize: CGRect = UIScreen.main.bounds
    let screenWidth = screensize.width
    let screenHeight = screensize.height
    var scrollView: UIScrollView!
    scrollView = UIScrollView(frame: CGRect(x: 0, y: 120, width: screenWidth, height: screenHeight))

    scrollView.addSubview(labelTwo)

    NSLayoutConstraint(item: labelTwo, attribute: .leading, relatedBy: .equal, toItem: scrollView, attribute: .leadingMargin, multiplier: 1, constant: 10).isActive = true
    NSLayoutConstraint(item: labelTwo, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 200).isActive = true
    NSLayoutConstraint(item: labelTwo, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .topMargin, multiplier: 1, constant: 10).isActive = true
    NSLayoutConstraint(item: labelTwo, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 30).isActive = true

    scrollView.contentSize = CGSize(width: screenWidth, height: 2000)
    view.addSubview(scrollView)

}

And the scroll view looks like this

enter image description here

Upvotes: 12

Related Questions