Agregar vistas en UIStackView mediante programación

Resuelto Altimir Antonov asked hace 54 años • 17 respuestas

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).

Altimir Antonov avatar Jan 01 '70 08:01 Altimir Antonov
Aceptado

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

UIStackView espaciado igual (centrado)

user1046037 avatar Jul 23 '2015 02:07 user1046037

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.

Oleg Popov avatar Sep 20 '2015 03:09 Oleg Popov

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)
])
Ashim Dahal avatar Dec 18 '2018 07:12 Ashim Dahal

UIStackViewutiliza 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, UIViewlas instancias no definen un tamaño de contenido intrínseco. Esto es algo que generalmente proporciona una subclase, como UILabelo UIButton.

Dado que la resistencia a la compresión de contenido y las prioridades de aceptación de contenido de dos nuevas UIViewinstancias 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 UILabelinstancias, 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.

Greg Brown avatar Sep 30 '2015 13:09 Greg Brown