objective example create code ios objective-c uiimageview autolayout uistackview

ios - example - uistackview swift 3



UIStackView cálculo erróneo de UIImageView height (2)

¡Lo descubrimos! Como se indica en los documentos, UIStackView está utilizando el intrinsicContentSize de sus UIStackView para calcular su altura.

UIImageView informa de su intrinsicContentSize como el tamaño completo de la imagen (como era de esperar). UIStackView estaba ignorando mi restricción de altura y solo usaba el tamaño de UIStackView intrinsicContentSize de la vista de imagen.

Para solucionarlo, he creado una subclase UIImageView que permite que un interlocutor establezca el intrinsicContentSize . Este código se puede encontrar aquí .

Luego, en mi UICollectionViewCell estoy configurando la subclase UIImageView '' intrinsicContentSize una vez que el pase de diseño se haya completado:

- (void)layoutSubviews { [super layoutSubviews]; // Constrain the image view''s content size to match the stackview''s width. self.imageView.constrainedSize = CGSizeMake(self.stackView.frame.size.width, self.stackView.frame.size.width); [super layoutSubviews];

}

Tengo una UIStackView contenida dentro de UICollectionViewCell para representar una publicación en una red social (estilo similar a las celdas de Instagram). El UIStackView contiene un encabezado de autor ( UIView personalizado), un UIImageView para la imagen de contenido, un UILabel para el cuerpo del mensaje y un UIToolbar para las acciones. La vista final se ve así.

La altura de UICollectionViewCell se establece configurando una celda de tamaño, de esta manera:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { NTVFeedBlogCollectionViewCell *cell = [[NTVFeedBlogCollectionViewCell alloc] initWithFrame:CGRectMake(10.0f, 0.0f, collectionView.frame.size.width - 20.0f, 900000.0)]; // ... // Configure the cell // ... [cell setNeedsLayout]; [cell layoutIfNeeded]; CGSize size = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; return CGSizeMake(CGRectGetWidth(collectionView.frame) - 20.0f, size.height); }

El problema es que UIImageView parece aumentar el tamaño de UICollectionViewCell, sin aumentar el tamaño de la vista de imagen. Este es el resultado cuando agrego una imagen grande a la vista de la imagen. El resultado deseado es que la imagen permanezca en una relación de aspecto de 1: 1, limitada al ancho de UIStackView.

El tamaño del espacio entre la etiqueta del cuerpo y el resto del contenido cambia según la imagen que uso. Esto me lleva a creer que UIStackView alguna manera está teniendo en cuenta el tamaño de la imagen para el tamaño de la celda solamente, ya que visualmente la vista de la imagen tiene su tamaño correcto. Como viste en la primera imagen publicada, la celda se establece perfectamente cuando la imagen de la vista de imagen no se ha configurado.

Aquí está el código de configuración para la vista de la pila, la vista de la imagen y las etiquetas:

self.stackView = [[UIStackView alloc] initWithFrame:CGRectZero]; self.stackView.translatesAutoresizingMaskIntoConstraints = NO; self.stackView.axis = UILayoutConstraintAxisVertical; self.stackView.distribution = UIStackViewDistributionFill; self.stackView.alignment = UIStackViewAlignmentFill; self.stackView.spacing = 10.0f; self.stackView.layoutMargins = UIEdgeInsetsMake(10.0f, 10.0f, 0.0f, 10.0f); self.stackView.layoutMarginsRelativeArrangement = YES; [self addSubview:self.stackView]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[stackView]-0-|" options:0 metrics:nil views:@{@"stackView": self.stackView}]]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[stackView]-0-|" options:0 metrics:nil views:@{@"stackView": self.stackView}]]; self.imageView = [[UIImageView alloc] initWithFrame:CGRectZero]; [self.imageView setImage:[UIImage imageNamed:@"sample_image.png"]]; self.imageView.translatesAutoresizingMaskIntoConstraints = NO; self.imageView.contentMode = UIViewContentModeScaleAspectFill; self.imageView.clipsToBounds = YES; self.imageView.layer.masksToBounds = YES; self.imageView.backgroundColor = [UIColor greenColor]; [self.imageView setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical]; [self.imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical]; [self.stackView addArrangedSubview:self.imageView]; [self.stackView addConstraint:[NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.stackView attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]]; self.bodyLabel = [[UILabel alloc] initWithFrame:CGRectZero]; [self.bodyLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical]; [self.bodyLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical]; self.bodyLabel.font = [UIFont ntv_lightFontWithSize:17.0f]; self.bodyLabel.textColor = [UIColor whiteColor]; self.bodyLabel.numberOfLines = 0; self.bodyLabel.text = @"While the stack view allows you to layout its contents without using Auto Layout directly, you still need to use Auto Layout to position the stack view, itself."; [self.stackView addArrangedSubview:self.bodyLabel]; self.accessoryView = [[NTVAccessoryView alloc] initWithFrame:CGRectZero]; self.accessoryView.viewModel = [NTVAccessoryManagerViewModel_Stubbed new]; [self.stackView addArrangedSubview:self.accessoryView];

¿Algunas ideas?


La otra solución, si no quieres hacerlo programáticamente, es usar 2 UIStackViews verticalmente. El UIStackView superior que contiene UIImageView, establece su restricción de altura para asumir, digamos el 70% de la altura de la supervista, y permite que el UIStackView inferior se coloque justo al lado del superior, por lo que ocupará el 30% de altura restante.

De esta manera, no importa cuán grande sea tu imagen, siempre tomará el 70% de la altura.