Agregar vistas en UIStackView mediante programación
Estoy intentando agregar vistas en UIStackView mediante programación. Por ahora mi código es:
UIView *view1 = [[UIView alloc]init];
view1.backgroundColor = [UIColor blackColor];
[view1 setFrame:CGRectMake(0, 0, 100, 100)];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor greenColor];
[view2 setFrame:CGRectMake(0, 100, 100, 100)];
[self.stack1 addArrangedSubview:view1];
[self.stack1 addArrangedSubview:view2];
Cuando implemento la aplicación, solo hay 1 vista y es de color negro (la vista 1 también obtiene los parámetros para la vista 2).
Las vistas de pila utilizan un tamaño de contenido intrínseco, por lo tanto, utilice restricciones de diseño para definir las dimensiones de las vistas.
Existe una manera sencilla de agregar restricciones rápidamente (ejemplo):
[view1.heightAnchor constraintEqualToConstant:100].active = true;
Código completo:
- (void) setup {
//View 1
UIView *view1 = [[UIView alloc] init];
view1.backgroundColor = [UIColor blueColor];
[view1.heightAnchor constraintEqualToConstant:100].active = true;
[view1.widthAnchor constraintEqualToConstant:120].active = true;
//View 2
UIView *view2 = [[UIView alloc] init];
view2.backgroundColor = [UIColor greenColor];
[view2.heightAnchor constraintEqualToConstant:100].active = true;
[view2.widthAnchor constraintEqualToConstant:70].active = true;
//View 3
UIView *view3 = [[UIView alloc] init];
view3.backgroundColor = [UIColor magentaColor];
[view3.heightAnchor constraintEqualToConstant:100].active = true;
[view3.widthAnchor constraintEqualToConstant:180].active = true;
//Stack View
UIStackView *stackView = [[UIStackView alloc] init];
stackView.axis = UILayoutConstraintAxisVertical;
stackView.distribution = UIStackViewDistributionEqualSpacing;
stackView.alignment = UIStackViewAlignmentCenter;
stackView.spacing = 30;
[stackView addArrangedSubview:view1];
[stackView addArrangedSubview:view2];
[stackView addArrangedSubview:view3];
stackView.translatesAutoresizingMaskIntoConstraints = false;
[self.view addSubview:stackView];
//Layout for Stack View
[stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = true;
[stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = true;
}
Nota: esto fue probado en iOS 9
Rápido 5.0
//Image View
let imageView = UIImageView()
imageView.backgroundColor = UIColor.blue
imageView.heightAnchor.constraint(equalToConstant: 120.0).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 120.0).isActive = true
imageView.image = UIImage(named: "buttonFollowCheckGreen")
//Text Label
let textLabel = UILabel()
textLabel.backgroundColor = UIColor.yellow
textLabel.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true
textLabel.heightAnchor.constraint(equalToConstant: 20.0).isActive = true
textLabel.text = "Hi World"
textLabel.textAlignment = .center
//Stack View
let stackView = UIStackView()
stackView.axis = NSLayoutConstraint.Axis.vertical
stackView.distribution = UIStackView.Distribution.equalSpacing
stackView.alignment = UIStackView.Alignment.center
stackView.spacing = 16.0
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(textLabel)
stackView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(stackView)
//Constraints
stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
Basado en la respuesta de @user1046037.
En Swift 4.2
let redView = UIView()
redView.backgroundColor = .red
let blueView = UIView()
blueView.backgroundColor = .blue
let stackView = UIStackView(arrangedSubviews: [redView, blueView])
stackView.axis = .vertical
stackView.distribution = .fillEqually
view.addSubview(stackView)
// stackView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
// autolayout constraint
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor),
stackView.leftAnchor.constraint(equalTo: view.leftAnchor),
stackView.rightAnchor.constraint(equalTo: view.rightAnchor),
stackView.heightAnchor.constraint(equalToConstant: 200)
])
UIStackView
utiliza restricciones internamente para posicionar sus subvistas organizadas. Las restricciones exactas que se crean dependen de cómo esté configurada la vista de pila. De forma predeterminada, una vista de pila creará restricciones que dispondrán sus subvistas organizadas en una línea horizontal, fijando las vistas inicial y final a sus propios bordes inicial y final. Entonces su código produciría un diseño similar a este:
|[view1][view2]|
El espacio que se asigna a cada subvista está determinado por una serie de factores que incluyen el tamaño del contenido intrínseco de la subvista y su resistencia a la compresión y las prioridades de adaptación al contenido. De forma predeterminada, UIView
las instancias no definen un tamaño de contenido intrínseco. Esto es algo que generalmente proporciona una subclase, como UILabel
o UIButton
.
Dado que la resistencia a la compresión de contenido y las prioridades de aceptación de contenido de dos nuevas UIView
instancias serán las mismas, y ninguna vista proporciona un tamaño de contenido intrínseco, el motor de diseño debe hacer su mejor estimación sobre qué tamaño debe asignarse a cada vista. En su caso, le está asignando a la primera vista el 100% del espacio disponible y nada a la segunda vista.
Si modifica su código para usar UILabel
instancias, obtendrá mejores resultados:
UILabel *label1 = [UILabel new];
label1.text = @"Label 1";
label1.backgroundColor = [UIColor blueColor];
UILabel *label2 = [UILabel new];
label2.text = @"Label 2";
label2.backgroundColor = [UIColor greenColor];
[self.stack1 addArrangedSubview:label1];
[self.stack1 addArrangedSubview:label2];
Tenga en cuenta que no es necesario que usted mismo cree explícitamente ninguna restricción. Este es el principal beneficio de su uso UIStackView
: oculta al desarrollador los detalles (a menudo desagradables) de la gestión de restricciones.