lanzamiento - ¿Cómo se puede obtener el tamaño de diseño automático de UICollectionViewCells en iOS 8?(systemLayoutSizeFittingSize devuelve el tamaño con altura cero en iOS 8)
ios 12 lanzamiento (8)
Estamos utilizando una solución temporal por ahora, copiada a continuación. Con suerte, estos problemas se resolverán antes del lanzamiento de iOS 8 y podemos eliminar esto. (El kludge asume el conocimiento del comportamiento implícito de la vista de contenido de Apple, y tenemos que hackear las referencias de las salidas de IB a cualquier restricción que transfiramos)
Notamos que también están eliminando todas las máscaras automáticas de guiones gráficos / NIB durante la actualización, lo cual tiene sentido dado que se supone que tiene un diseño automático, pero las vistas de la colección aún se remontan a los resortes y puntales. Tal vez esto ha sido pasado por alto en la purga?
--Dan
/**
Kludge around cell sizing issues for iOS 8 and deployment to iOS 7 when compiled for 8. Call this on the collection view cell before it is used, such as in awakeFromNib. Because this manipulates top-level constraints, any references to such initial constraints, such as from IB outlets, will be invalidated.
Issue 1: As of iOS 8 Beta 5, systemLayoutSizeFittingSize returns height 0 for a UICollectionViewCell. In IB, cells have an implicit contentView, below which views placed in IB as subviews of the cell are actually placed. However, constraints set between these subviews and its superview are placed on the cell, rather than the contentView (which is their actual superview). This should be OK, as a constraint among items may be placed on any common ancestor of those items, but this is not playing nice with systemLayoutSizeFittingSize. Transferring those constraints to be on the contentView seems to fix the issue.
Issue 2: In iOS 7, prior to compiling against iOS 8, the resizing mask of the content view was being set by iOS to width+height. When running on iOS 7 compiled against iOS 8 Beta 5, the resizing mask is None, resulting in constraints effecting springs for the right/bottom margins. Though this starts out the contentView the same size as the cell, changing the cell size, as we do in the revealing list, is not tracked by changing it''s content view. Restore the previous behavior.
Moving to dynamic cell sizing in iOS 8 may circumvent this issue, but that remedy isn''t available in iOS 7.
*/
+ (void)kludgeAroundIOS8CollectionViewCellSizingIssues:(UICollectionViewCell *)cell {
// transfer constraints involving descendants on cell to contentView
UIView *contentView = cell.contentView;
NSArray *cellConstraints = [cell constraints];
for (NSLayoutConstraint *cellConstraint in cellConstraints) {
if (cellConstraint.firstItem == cell && cellConstraint.secondItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:contentView attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:cellConstraint.secondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
} else if (cellConstraint.secondItem == cell && cellConstraint.firstItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:cellConstraint.firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:contentView attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
}
}
// restore auto-resizing mask to iOS 7 behavior
contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
}
Desde iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
devuelve un tamaño con altura de 0.
Esto es lo que hace el código:
Para determinar el tamaño de la celda en un UICollectionView
en iOS 7, uso systemLayoutSizeFittingSize:
en una celda definida en un archivo xib utilizando el diseño automático. El tamaño depende del tamaño de fuente de una UILabel
como una subvista de UICollectionViewCell
en mi archivo xib. La fuente de la etiqueta se establece en UIFontTextStyleBody
. Entonces, básicamente, el tamaño de la celda depende de la configuración del tamaño de fuente hecha en iOS 7.
Aquí está el código en sí:
+ (CGSize)cellSize {
UINib *nib = [UINib nibWithNibName:NSStringFromClass([MyCollectionViewCell class]) bundle:nil];
// Assumption: The XIB file only contains a single root UIView.
UIView *rootView = [[nib instantiateWithOwner:nil options:nil] lastObject];
if ([rootView isKindOfClass:[MyCollectionViewCell class]]) {
MyCollectionViewCell *sampleCell = (MyCollectionViewCell*)rootView;
sampleCell.label.text = @"foo"; // sample text without bar
[sampleCell setNeedsLayout];
[sampleCell layoutIfNeeded];
return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}
return CGSizeZero;
}
Funciona perfectamente bien en iOS 7, pero no en iOS 8. Lamentablemente, no tengo ni idea de por qué.
¿Cómo puedo obtener el tamaño de diseño automático de UICollectionViewCells en iOS 8?
PS: utilizando
return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
en lugar de
return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
Como alguien podría sugerir, no hace ninguna diferencia.
Esto no es un error, he estado lidiando con este problema por algún tiempo y he intentado diferentes cosas, a continuación doy los pasos que me han funcionado:
1) use contentView [sampleCell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];
2) puede crear su propio contentView y tener las subvistas agregadas al contentView, no olvide fijar la parte superior, inferior, izquierda y derecha del contentView si está utilizando un contentView personalizado al superView, si no lo hace haga esto y la altura será 0, aquí también dependiendo de sus requisitos para. por ejemplo, no fije la parte inferior del contentView a la superView para que la altura de la vista pueda variar, pero la fijación es importante y determinar cuál depende de sus requisitos.
3) establezca las restricciones correctamente en el generador de interfaz según sus requisitos, hay ciertas restricciones que no se pueden agregar en el generador de interfaz, pero luego puede agregarlas en viewDidLoad del viewController.
Así que mi entrada de 2 centavos es que las restricciones se deben establecer correctamente en el generador de interfaces para systemLayoutSizeFittingSize: UILayoutFittingCompressedSize para devolver las dimensiones correctas, esta es la solución.
Fue un error en las versiones beta de iOS 8. Finalmente se arregla con para iOS 8 GB (Build 12A365). Así que para mí ahora funciona con el mismo código que escribí para iOS 7. (vea la pregunta)
Lo que debe hacer es envolver todo su contenido en una vista de contenedor, luego llame:
return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
Su celda debería tener este aspecto: celda -> containerView -> sub vistas
Esto funciona tanto en ios7 como en ios8.
Supuestamente, en ios8, todo lo que tiene que hacer es configurar el presupuesto estimado y la celda se ajustará automáticamente automáticamente. Al parecer eso no funciona a partir de la beta 6.
Parece que esto oficialmente es un error: presenté un informe que se cerró como un duplicado de este
Informará cuando Beta 6 esté fuera.
[ Actualización : funciona correctamente en la semilla GM de iOS 8, y Apple ha cerrado el error]
Se trata de un error en xCode6 y iOS 8 SDK que se ejecuta en dispositivos iOS7 :) Casi arruinó mi día. Finalmente, funcionó con el siguiente código en la subclase UICollectionViewCell. Espero que esto se solucione con la próxima versión.
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
self.contentView.frame = bounds;
}
Tuve el mismo problema para UITableViewCells e iOS 7 (ios8 funciona perfectamente), pero la solución "Triet Luong" funcionó para mí:
return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
tal vez tenga algún tipo de restricción errónea, debería especificar tanto el espacio superior como el espacio inferior virtical entre su UIView y contentView , también tuve este problema antes, ya que acabo de especificar el espacio superior y no especifiqué el espacio inferior. a contentView