// using a UIScrollView class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground let scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.showsVerticalScrollIndicator = false scrollView.showsHorizontalScrollIndicator = false scrollView.bounces = true self.view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), scrollView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20), scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) // Create the UILabels, UIImageView, and UIButton let titleLabel = UILabel() titleLabel.text = "Your Intelligence Types" titleLabel.font = UIFont(name: "Inter-Bold", size: 20) titleLabel.textAlignment = .center // Create the UILabels, UIImageView, and UIButton let descriptionLbl = UILabel() descriptionLbl.text = "Different types of intelligence highlight the diverse ways people think, solve problems, and interact with the world around them." descriptionLbl.font = UIFont(name: "Inter-Regular", size: 14) descriptionLbl.textAlignment = .left descriptionLbl.numberOfLines = 0 titleLabel.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(titleLabel) descriptionLbl.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(descriptionLbl) // so we can see the framing scrollView.backgroundColor = .init(white: 0.95, alpha: 1.0) titleLabel.backgroundColor = .cyan descriptionLbl.backgroundColor = .green let cg = scrollView.contentLayoutGuide let fg = scrollView.frameLayoutGuide // Set constraints for the stackView NSLayoutConstraint.activate([ titleLabel.topAnchor.constraint(equalTo: cg.topAnchor, constant: 20), titleLabel.leadingAnchor.constraint(equalTo: cg.leadingAnchor, constant: 20), // don't set a trailing anchor //titleLabel.trailingAnchor.constraint(equalTo: cg.trailingAnchor, constant: -20), // set the title label width to the width of the scrollView's frame layout guide // minus 40-points (20-points on each side) titleLabel.widthAnchor.constraint(equalTo: fg.widthAnchor, constant: -40.0), titleLabel.heightAnchor.constraint(equalToConstant: 30) ]) // Set constraints for the stackView NSLayoutConstraint.activate([ descriptionLbl.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 20), descriptionLbl.leadingAnchor.constraint(equalTo: cg.leadingAnchor, constant: 20), // don't hard-code the width //descriptionLbl.widthAnchor.constraint(equalToConstant: 350), // set the descriptionLbl label width to the width of the scrollView's frame layout guide // minus 40-points (20-points on each side) descriptionLbl.widthAnchor.constraint(equalTo: fg.widthAnchor, constant: -40.0), // if you want the description label height to "auto-size" // don't set the height here //descriptionLbl.heightAnchor.constraint(equalToConstant: 60) ]) var previousProgressView : UIProgressView? = nil let previousTitleHeight: CGFloat = 30 let progressViewHeight: CGFloat = 20 let labelHeight: CGFloat = 20 let verticalSpacing: CGFloat = 20 var n = 0; // I don't have your data, so let's just add 20 progress view's (witht their labels) //for (key, value) in totalTypes { for i in 0..<20 { let typeLabel = UILabel() //typeLabel.text = key typeLabel.text = "key \(i)" typeLabel.font = UIFont(name: "Inter-Bold", size: 16) typeLabel.textAlignment = .left typeLabel.backgroundColor = .yellow typeLabel.translatesAutoresizingMaskIntoConstraints = false let iprogressView = UIProgressView(progressViewStyle: .bar) iprogressView.trackTintColor = UIColor(red: 0.07, green: 0.45, blue: 0.87, alpha: 0.1) iprogressView.tintColor = UIColor(red: 0.07, green: 0.45, blue: 0.87, alpha: 1.00) iprogressView.layer.cornerRadius = 4 iprogressView.clipsToBounds = true //iprogressView.setProgress(Float(userTypes[key] ?? 0) / Float(value), animated: true) iprogressView.setProgress(Float(i) * 0.05, animated: true) iprogressView.translatesAutoresizingMaskIntoConstraints = false let transform : CGAffineTransform = CGAffineTransform(scaleX: 1.0, y: 3.0) iprogressView.transform = transform let progressLabel = UILabel() //let progressValue = round(((Float(userTypes[key] ?? 0) / Float(value)) * 100) * 100) / 100 let progressValue = String(format: "%0.2f", Float(i) * 0.05 * 100.0) progressLabel.text = "\(progressValue) %" progressLabel.translatesAutoresizingMaskIntoConstraints = false progressLabel.font = UIFont(name: "Inter-Regular", size: 16) progressLabel.backgroundColor = .systemYellow scrollView.addSubview(typeLabel) scrollView.addSubview(iprogressView) scrollView.addSubview(progressLabel) NSLayoutConstraint.activate([ typeLabel.topAnchor.constraint(equalTo: previousProgressView?.bottomAnchor ?? descriptionLbl.bottomAnchor, constant: previousProgressView == nil ? verticalSpacing : verticalSpacing), typeLabel.leadingAnchor.constraint(equalTo: cg.leadingAnchor, constant: 20), //typeLabel.trailingAnchor.constraint(equalTo: cg.trailingAnchor, constant: -20), typeLabel.heightAnchor.constraint(equalToConstant: 20), iprogressView.topAnchor.constraint(equalTo: typeLabel.bottomAnchor, constant: 20), iprogressView.leadingAnchor.constraint(equalTo: cg.leadingAnchor, constant: 20), iprogressView.widthAnchor.constraint(equalToConstant: 200), iprogressView.heightAnchor.constraint(equalToConstant: 3), // Position the label next to the progressView progressLabel.leadingAnchor.constraint(equalTo: iprogressView.trailingAnchor, constant: 10), progressLabel.centerYAnchor.constraint(equalTo: iprogressView.centerYAnchor) ]) // Update the previousProgressView reference previousProgressView = iprogressView n += 1 } // we MUST have a bottom constraint to let the scrollView know it has content to scroll previousProgressView?.bottomAnchor.constraint(equalTo: cg.bottomAnchor, constant: -20.0).isActive = true // we're using auto-layout / constraints ... don't do this // Set the content size of the scrollView //let totalContentHeight = (CGFloat(totalTypes.count) * (labelHeight + progressViewHeight + verticalSpacing + CGFloat(100))) + verticalSpacing + CGFloat(2000) //scrollView.contentSize = CGSize(width: self.view.frame.width, height: totalContentHeight) } } // NOTE: based on the layout, this code assumes we want vertical scrolling only... so, no need to set constraints to the content layout guide trailing.