working uitableviewcell not español ios uitableview cocoa-touch autolayout ios-autolayout

ios - uitableviewcell - ¿Qué es NSLayoutConstraint "UIView-Encapsulated-Layout Height" y cómo debo forzarlo para que vuelva a calcular de manera limpia?



uitableviewautomaticdimension not working (12)

Tengo un UITableView ejecutándose bajo iOS 8 y estoy usando alturas de celdas automáticas de restricciones en un guión gráfico.

Una de mis celdas contiene un solo UITextView y lo necesito para contratar y expandir en función de la información del usuario: toque para reducir / expandir el texto.

Estoy haciendo esto agregando una restricción de tiempo de ejecución a la vista de texto y cambiando la constante en la restricción en respuesta a los eventos del usuario:

-(void)collapse:(BOOL)collapse; { _collapsed = collapse; if(collapse) [_collapsedtextHeightConstraint setConstant: kCollapsedHeight]; // 70.0 else [_collapsedtextHeightConstraint setConstant: [self idealCellHeightToShowFullText]]; [self setNeedsUpdateConstraints]; }

Cuando hago esto, lo tableView en tableView actualizaciones de tableView y llamo [tableView setNeedsUpdateConstraints] :

[tableView beginUpdates]; [_briefCell collapse:!_showFullBriefText]; [tableView setNeedsUpdateConstraints]; // I have also tried // [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop]; // with exactly the same results. [tableView endUpdates];

Cuando hago esto, mi celda se expande (y anima mientras lo hace) pero recibo una advertencia de restricciones:

2014-07-31 13:29:51.792 OneFlatEarth[5505:730175] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don''t want. Try this: (1) look at each constraint and try to figure out which you don''t expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you''re seeing NSAutoresizingMaskLayoutConstraints that you don''t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200''Brief text: Lorem Ipsum i...''(388)]>", "<NSLayoutConstraint:0x7f94dced2260 V:[UITextView:0x7f94d9b2b200''Brief text: Lorem Ipsum i...'']-(15)-| (Names: ''|'':UITableViewCellContentView:0x7f94de5773a0 )>", "<NSLayoutConstraint:0x7f94dced2350 V:|-(6)-[UITextView:0x7f94d9b2b200''Brief text: Lorem Ipsum i...''] (Names: ''|'':UITableViewCellContentView:0x7f94de5773a0 )>", "<NSLayoutConstraint:0x7f94dced6480 ''UIView-Encapsulated-Layout-Height'' V:[UITableViewCellContentView:0x7f94de5773a0(91)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200''Brief text: Lorem Ipsum i...''(388)]>

388 es mi altura calculada, las otras restricciones en el UITextView son mías de Xcode / IB.

El último me está molestando, supongo que UIView-Encapsulated-Layout-Height es la altura calculada de la celda cuando se procesa por primera vez - (configuro mi altura UITextView para que sea> = 70.0) sin embargo, no parece justo cuando esta restricción derivada anula una cnstraint de usuario actualizada.

Peor aún, aunque el código de diseño dice que está intentando romper mi restricción de altura, no lo hace, sino que vuelve a calcular la altura de la celda y todo se dibuja como me gustaría.

Entonces, ¿qué es NSLayoutConstraint UIView-Encapsulated-Layout-Height (supongo que es la altura calculada para el tamaño automático de celdas) y cómo debo forzar que se vuelva a calcular limpiamente?


Ajustar el tamaño de la vista de texto para que se ajuste a su contenido y actualizar la constante de restricción de altura a la altura resultante, corrigió el conflicto de restricción UIView-Encapsulated-Layout-Height para mí, por ejemplo:

[self.textView sizeToFit]; self.textViewHeightConstraint.constant = self.textView.frame.size.height;


Como lo mencionó Jesse en el comentario de la pregunta, esto funciona para mí:

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

Para su información, este problema no ocurre en iOS 10.


Después de pasar algunas horas rascándome la cabeza con este error, finalmente encontré una solución que funcionó para mí. mi principal problema era que tenía múltiples nibs registradas para diferentes tipos de células, pero a un tipo de célula se le permitía específicamente tener diferentes tamaños (no todas las instancias de esa célula van a ser del mismo tamaño). así que el problema surgió cuando la vista de tabla estaba tratando de sacar de la cola una celda de ese tipo y resultó que tenía una altura diferente. Lo resolví estableciendo

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.frame = CGRectMake(0, 0, self.frame.size.width, {correct height});

Cada vez que la celda tenía sus datos para calcular su tamaño. Me imagino que puede estar en

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

algo como

cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; cell.frame = CGRectMake(0, 0, self.frame.size.width, {correct height});

¡Espero que esto ayude!


En lugar de informar a la vista de tabla para actualizar sus restricciones, intente volver a cargar la celda:

[tableView beginUpdates]; [_briefCell collapse:!_showFullBriefText]; [tableView reloadRowsAtIndexPaths:@[[tableView indexPathForCell:_briefCell]] withRowAnimation:UITableViewRowAnimationNone]; [tableView endUpdates];

UIView-Encapsulated-Layout-Height es probablemente la altura que calculó la vista de tabla para la celda durante la carga inicial, en función de las restricciones de la celda en ese momento.


Establezca este view.translatesAutoresizingMaskIntoConstraints = NO; debe resolver este problema.


Otra posibilidad:

Si está utilizando el diseño automático para calcular la altura de la celda (la altura de contentView, la mayoría de las veces como se muestra a continuación), y si tiene un separador de vista útil, debe agregar la altura del separador para volver a la altura de la celda. Una vez que obtenga la altura correcta, no tendrá esa advertencia de autolayout.

- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell { [sizingCell setNeedsLayout]; [sizingCell layoutIfNeeded]; CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; return size.height; // should + 1 here if my uitableviewseparatorstyle is not none }


Pude hacer que desaparezca la advertencia especificando una priority en uno de los valores en la restricción que los mensajes de advertencia dicen que tuvo que interrumpir (debajo de "Will attempt to recover by breaking constraint" ). Parece que mientras establezco la prioridad en algo mayor a 49 , la advertencia desaparece.

Para mí esto significó cambiar mi restricción, la advertencia decía que intentaba romper:

@"V:|[contentLabel]-[quoteeLabel]|"

a:

@"V:|-0@500-[contentLabel]-[quoteeLabel]|"

De hecho, puedo agregar una prioridad a cualquiera de los elementos de esa restricción y funcionará. No parece importar cuál. Mis celdas terminan en la altura adecuada y la advertencia no se muestra. Roger, para su ejemplo, intente agregar @500 justo después de la restricción de valor de altura 388 (por ejemplo, 388@500 ).

No estoy completamente seguro de por qué esto funciona, pero he investigado un poco. En la enumeración NSLayoutPriority , parece que el nivel de prioridad NSLayoutPriorityFittingSizeCompression es 50 . La documentación para ese nivel de prioridad dice:

Cuando envía un mensaje de ajuste de tamaño a una vista, se calcula el tamaño más pequeño que sea lo suficientemente grande para el contenido de la vista. Este es el nivel de prioridad con el que la vista desea ser lo más pequeña posible en ese cálculo. Es bastante bajo. En general, no es apropiado hacer una restricción exactamente en esta prioridad. Quieres ser superior o inferior.

La documentation para el mensaje de fittingSize referenciado dice:

El tamaño mínimo de la vista que satisface las restricciones que mantiene. (solo lectura)

AppKit establece esta propiedad en el mejor tamaño disponible para la vista, considerando todas las restricciones que mantiene y sus subvistas y satisface una preferencia para hacer la vista lo más pequeña posible. Los valores de tamaño en esta propiedad nunca son negativos.

No he cavado más allá de eso, pero parece tener sentido que esto tenga algo que ver con el problema.


Pude resolver este error eliminando un cell.layoutIfNeeded() que tenía en el tableView mi tableView .


Recibí un mensaje como este:

Incapaz de satisfacer simultáneamente las restricciones ...
...
...
...
NSLayoutConstraint: 0x7fe74bdf7e50 ''UIView-Encapsulated-Layout-Height'' V: [UITableViewCellContentView: 0x7fe75330c5c0 (21.5)]
...
...
Intentará recuperarse rompiendo la restricción NSLayoutConstraint: 0x7fe0f9b200c0 UITableViewCellContentView: 0x7fe0f9b1e090.bottomMargin == UILabel: 0x7fe0f9b1e970.bottom

Estoy usando un UITableViewCell personalizado con UITableViewAutomaticDimension para la altura. Y también he implementado el método estimatedHeightForRowAtIndex: .

La restricción que me estaba dando problemas se parecía a esto.

[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[title]-|" options:0 metrics:nil views:views];

Cambiar la restricción a esto solucionará el problema, pero como otra respuesta, sentí que esto no era correcto, ya que reduce la prioridad de una restricción que quiero que se me solicite:

[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-6@999-[title]-6@999-|" options:0 metrics:nil views:views];

Sin embargo, lo que noté es que si realmente elimino la prioridad, esto también funciona y no obtengo los registros de restricción de ruptura:

[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-6-[title]-6-|" options:0 metrics:nil views:views];

Esto es un poco misterioso en cuanto a cuál es la diferencia entre |-6-[title]-6-| y |-[title-| . Pero especificar el tamaño no es un problema para mí y se elimina de los registros, y no necesito reducir la prioridad de mis restricciones requeridas.


TableView obtiene la altura para la celda en indexPath del delegado. a continuación, obtener celular de cellForRowAtIndexPath :

top (10@1000) cell bottom (0@1000)

si cell.contentView.height: 0 // <-> (UIView-Encapsulated-Layout-Height: 0 @ 1000) arriba (10 @ 1000) en conflicto con (UIView-Encapsulated-Layout-Height: 0 @ 1000),

debido a que las prioridades son iguales a 1000. Necesitamos una prioridad superior establecida bajo la prioridad de UIView-Encapsulated-Layout-Height .


Tengo un escenario similar: una vista de tabla con una celda de fila, en la que hay algunas líneas de objetos UILabel. Estoy usando iOS 8 y autolayout.

Cuando giré obtuve el sistema incorrecto, calculé la altura de la fila (43.5 es mucho menor que la altura real). Parece que:

"<NSLayoutConstraint:0x7bc2b2c0 ''UIView-Encapsulated-Layout-Height'' V:[UITableViewCellContentView:0x7bc37f30(43.5)]>"

No es solo una advertencia. El diseño de mi celda de vista de tabla es terrible: todo el texto se superpone en una línea de texto.

Me sorprende que la siguiente línea "arregle" mi problema mágicamente (la reproducción automática no se queja y obtengo lo que espero en la pantalla):

myTableView.estimatedRowHeight = 2.0; // any number but 2.0 is the smallest one that works

Con o sin esta línea:

myTableView.rowHeight = UITableViewAutomaticDimension; // by itself this line only doesn''t help fix my specific problem


Trate de reducir la prioridad de su _collapsedtextHeightConstraint a 999. De esa manera, el sistema suministró la UIView-Encapsulated-Layout-Height siempre tiene prioridad.

Se basa en lo que devuelve en -tableView:heightForRowAtIndexPath: Asegúrese de devolver el valor correcto y su propia restricción y la generada debe ser la misma. La prioridad más baja para su propia restricción solo se necesita temporalmente para evitar conflictos mientras las animaciones de colapsar / expandir están en vuelo.