Skip to content

Instantly share code, notes, and snippets.

@twostraws
Created June 10, 2015 19:06
Show Gist options
  • Select an option

  • Save twostraws/a02d4cc09fc7bc16859c to your computer and use it in GitHub Desktop.

Select an option

Save twostraws/a02d4cc09fc7bc16859c to your computer and use it in GitHub Desktop.
//
// SimpleScrollingStack.swift
// A super-simple demo of a scrolling UIStackView in iOS 9
//
// Created by Paul Hudson on 10/06/2015.
// Learn Swift at www.hackingwithswift.com
// @twostraws
//
import UIKit
class ViewController: UIViewController {
var scrollView: UIScrollView!
var stackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))
stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .Vertical
scrollView.addSubview(stackView)
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[stackView]|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[stackView]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))
for _ in 1 ..< 100 {
let vw = UIButton(type: UIButtonType.System)
vw.setTitle("Button", forState: .Normal)
stackView.addArrangedSubview(vw)
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)
}
}
@Jon889

Jon889 commented Feb 5, 2016

Copy link
Copy Markdown

In line 44 you can do scrollView.contentSize = stackView.frame.size

Doesn't seem much point making a new CGSize.

@cargath

cargath commented Mar 18, 2016

Copy link
Copy Markdown

Hm, when i replace the UIButtons with UIViews, they don't appear. Does anyone know what i am doing wrong?

for _ in 1 ..< 100 {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 42, height: 42))
    view.backgroundColor = UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0)
    stackView.addArrangedSubview(view)
}

@luzemma

luzemma commented Apr 17, 2016

Copy link
Copy Markdown

Hi cargath!

You need to put this line before add the view "view.heightAnchor.constraintEqualToConstant(100).active = true". It works for me.

@JamWils

JamWils commented May 9, 2016

Copy link
Copy Markdown

@cargath, a UIView has no intrinsic content size like the UIButton. You have to give each one a size so the UIStackView can figure out how to lay it out.

@lucasp90

lucasp90 commented Jun 1, 2016

Copy link
Copy Markdown

I've managed to make it work adding what @rzulkoski pointed out. Thanks a lot!!

ghost commented Jun 28, 2016

Copy link
Copy Markdown

@twostraws I've taken this example and tried to center align the buttons, and it doesn't seem to work, does anyone know why ?

Here's a detailed explanation of this problem: http://stackoverflow.com/q/38074366/502130

UPDATE

I've fixed the center alignment problem by setting an extra equal width constraint on the scrollView with the stackView

scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[stackView(==scrollView)]", options: .AlignAllCenterX, metrics: nil, views: ["stackView": stackView, "scrollView": scrollView]))

@CGS-Christopher-Seidl

Copy link
Copy Markdown

This is great, it really helped me with my project!

@DevAndArtist

DevAndArtist commented Aug 15, 2016

Copy link
Copy Markdown

@twostraws

Here is a better trick!

Remove this:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)       
}

And add | to your constraints:

scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[stackView]|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))

Setting Top and Bottom constraints doesn't mean setting a fixed height on UIScrollView.

Learned that here.

@falnatsheh

falnatsheh commented Jul 13, 2017

Copy link
Copy Markdown

Awesome! I converted the constraints to SnapKit and incorporated @DevAndArtist note, you could view the code here.

@nicolas-miari

Copy link
Copy Markdown

Why is it .AlignAllCenterX for both "H" and "V"? Shouldn't it be .AlignAllCenterY on each second line?

@krishnastvSMSC

Copy link
Copy Markdown

Tap action is not working for StackView objects, how we can add tap gestures for this scroll of stack view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment