
UIStackView en UIKit con Swift en Español - Curso iOS
Un UIStackView en UIKit sirve para agrupar vistas una al lado de la otra, o una debajo de la otra con el mínimo esfuerzo. Esto significa que nosotros no nos encargamos de añadir las constraints de Auto Layout, sino que lo hace el UIStackView por nosotros.
Tabla de contenido

Hoy en SwiftBeta vamos a crear nuestro primer UIStackView. Los UIStackViews nos sirven para colocar una colección de vistas una encima de otra, o una al lado de la otra, depende de como configuremos nuestro StackView, si horizontal o vertical. Vamos a ver estas dos configuraciones en el post de hoy. Al usar un UIStackView nos ahorramos crear las constraints de sus subvistas, ya que el StackView lo hace por nosotros. Es decir, si queremos apilar una serie de vistas, el UIStackView lo hace por nosotros. Como ejemplo práctico vamos a crear una vista que va a simular una pantalla de In App Purchases, donde un user podrá seleccionar el precio de la In App Purchase que quiere consumir dentro de nuestra app.
Creamos el proyecto en Xcode
Lo primero de todo que vamos hacer es crear el proyecto en Xcode. Recurda seleccionar como interfaz Storyboard (UIKit). Y una vez creado el proyecto nos vamos al ViewController. Allí dentro vamos a crear nuestro primer UIStackView.
class ViewController: UIViewController {
private let swiftBetaStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(swiftBetaStackView)
NSLayoutConstraint.activate([
swiftBetaStackView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
swiftBetaStackView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
swiftBetaStackView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
])
}
}
Hemos creado nuestro UIStackView, lo hemos añadido a la vista del ViewController y hemos añadido las constraints. Ahora mismo las vistas de nuestro StackView están vacías. Lo que vamos hacer es crear varios UIButton y los vamos a añadir a las arrangedSubviews del StackView.
class ViewController: UIViewController {
private let swiftBetaStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(swiftBetaStackView)
NSLayoutConstraint.activate([
swiftBetaStackView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
swiftBetaStackView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
swiftBetaStackView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
])
["1.99€", "2.99€", "14.99€", "24.99€"].forEach { price in
let button = UIButton(type: .system)
var configuration = UIButton.Configuration.borderedTinted()
configuration.title = price
configuration.subtitle = "Suscripción"
configuration.image = UIImage(systemName: "eurosign.circle.fill")
configuration.imagePadding = 12
configuration.baseBackgroundColor = .systemBlue
button.configuration = configuration
swiftBetaStackView.addArrangedSubview(button)
}
}
}
Ahora si compilamos, vamos a ver el resultado de nuestro StackView con los UIButtons que hemos añadido.

En el simulador aparece que nuestro StackView ha distribuido las vistas una al lado de la otra, pero podemos especificar el eje vertical o horizontal. En este caso, por defecto es el eje horizontal, vamos a cambiar esta propiedad en nuestro StackView.
private let swiftBetaStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
return stackView
}()

Si te fijas, ahora en lugar de añadir un UIButton uno al lado del otro, lo que ha hecho ha sido poner uno encima del otro. Pero, aún podemos configurar más parámetros de nuestro UIStackView, como por ejemplo el margen que queremos entre las vistas que hay dentro del StackView. Para ello, vamos a modificar un propiedad llamada spacing del UIStackView.
private let swiftBetaStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 20
return stackView
}()
Vamos a compilar y vamos a ver el resultado

Poco a poco ya va cogiendo forma nuestro UIStackView. Puedes jugar con más propiedades dentro del StackView, como por ejemplo el alignment o la distribución. Vamos a ver la primera, si añadimos un alignment de leading, center o trailing podemos ver como cambiar el tamaño de nuestros UIButtons dentro del StackView:
private let swiftBetaStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 20
stackView.alignment = .leading
return stackView
}()
Vamos a compilar nuestra aplicación para ver el resultado:

Vamos a borrar el alignment, y vamos a continuar. Lo que vamos hacer ahora es añadir un UILabel. Este UILabel será el título de nuestra pantall:
class ViewController: UIViewController {
private let swiftBetaLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "🤑 In App Purchases 🤑"
label.textAlignment = .center
label.font = .systemFont(ofSize: 32)
return label
}()
private let swiftBetaStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.spacing = 20
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(swiftBetaLabel)
view.addSubview(swiftBetaStackView)
NSLayoutConstraint.activate([
swiftBetaLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 20),
swiftBetaLabel.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
swiftBetaLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
swiftBetaStackView.topAnchor.constraint(equalTo: swiftBetaLabel.bottomAnchor, constant: 32),
swiftBetaStackView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
swiftBetaStackView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
])
["1.99€", "2.99€", "14.99€", "24.99€"].forEach { price in
let button = UIButton(type: .system)
var configuration = UIButton.Configuration.borderedTinted()
configuration.title = price
configuration.subtitle = "Suscripción"
configuration.image = UIImage(systemName: "eurosign.circle.fill")
configuration.imagePadding = 12
configuration.baseBackgroundColor = .systemBlue
button.configuration = configuration
swiftBetaStackView.addArrangedSubview(button)
}
}
}
Si compilamos la aplicación este sería el resultado:

Justo lo que queríamos!
Conclusión
Hoy hemos aprendido a crear un UIStackView y hemos visto lo fácil que es añadir subvistas dentro de él. Es fácil y simple, nos ahorramos añadir constraints para posicionar todas las subvistas.