UILabel no ajusta el texto correctamente a veces (diseño automático)

Tengo una configuración de uilabel en una vista. No tiene una restricción de ancho, pero su ancho está determinado por una restricción inicial a la imagen en miniatura y una restricción al final de la vista.

La etiqueta está configurada para tener 0 líneas y para ajuste de palabras. Mi entendimiento es que esto debería hacer que el marco de la uilabel crezca, y de hecho lo hace a veces. (Antes del diseño automático, calcularía y actualizaría el marco de la etiqueta en el código).

Entonces el resultado es que funciona correctamente en algunos casos y no en otros. Vea que la mayoría de las celdas funcionan correctamente allí, pero la última celda parece ser demasiado grande. De hecho es el tamaño correcto. El título "Fair Oaks Smog Check Test" en realidad termina con "Sólo". Así que mi cálculo para el tamaño de la celda es correcto, debería ser ese tamaño. Sin embargo, la etiqueta no envuelve el texto por cualquier razón. El ancho del marco no se extiende hacia la derecha, por lo que ese no es el problema.

Entonces, ¿qué está pasando aquí? Es 100% coherente, siempre en esa celda y no en las que están arriba, lo que me hace pensar que está relacionado con el tamaño del texto, y UILabel no vuelve a colocar el texto una vez que esta vista se agrega a la celda (que lo hace en realidad menor ancho a lo largo).

¿Alguna idea?

Alguna informacion adicional

La altura de las celdas se calcula a partir de una celda de muestra que creo y almaceno en una variable estática:

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (self.items.count == 0) {
        return 60;
    }
    static TCAnswerBuilderCell *cell = nil;
    static dispatch_once_t pred;

    dispatch_once(&pred,
                  ^{
                      // get a sample cellonce
                      cell = [tableView dequeueReusableCellWithIdentifier:TC_ANSWER_BUILDER_CELL];
                  });
    [cell configureCellWithThirdPartyObject:self.items[indexPath.row]];
    return [cell heightForCellWithTableWidth:self.tableView.frame.size.width];
}

Configuro la celda con mi objeto de datos sobre la marcha, y luego invoco un método que tengo en ella que calcula la altura de la celda con un ancho de tabla dado (no siempre se puede confiar en que el marco de la celda sea correcto inicialmente).

A su vez, esto llama a un método de altura, ya que realmente es donde vive la etiqueta:

- (CGFloat)heightForCellWithTableWidth:(CGFloat)tableWidth {
    // subtract 38 from the constraint above
    return [self.thirdPartyAnswerView heightForViewWithViewWidth:tableWidth - 38];
}

Este método determina la altura al calcular el ancho correcto de la etiqueta y luego hacer un cálculo:

- (CGFloat)heightForViewWithViewWidth:(CGFloat)viewWidth {
    CGFloat widthForCalc = viewWidth - self.imageFrameLeadingSpaceConstraint.constant - self.thumbnailFrameWidthConstraint.constant - self.titleLabelLeadingSpaceConstraint.constant;
    CGSize size = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(widthForCalc, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
    CGFloat returnHeight = self.frame.size.height - self.titleLabel.frame.size.height + size.height;
    CGFloat height = returnHeight < self.frame.size.height ? self.frame.size.height : returnHeight;
    return height;
}

Esto funciona al 100% correctamente.

Las celdas se crean obviamente en cellForRowAtIndexPath y se configuran de inmediato:

if (self.items.count > 0) {
    TCAnswerBuilderCell *cell = [tableView dequeueReusableCellWithIdentifier:TC_ANSWER_BUILDER_CELL forIndexPath:indexPath];
    [cell configureCellWithThirdPartyObject:self.items[indexPath.row]];
    return cell;
}

En la configuración de la celda, mi vista se carga desde una punta (se reutiliza en otro lugar, por lo que no está directamente en la celda). La celda lo agrega de la siguiente manera:

- (void) configureCellWithThirdPartyObject:(TCThirdPartyObject *)object {
    self.detailDisclosureImageView.hidden = NO;
    if (!self.thirdPartyAnswerView) {
        self.thirdPartyAnswerView = [TCThirdPartyAPIHelper thirdPartyAnswerViewForThirdPartyAPIServiceType:object.thirdPartyAPIType];
        self.thirdPartyAnswerView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.contentView addSubview:self.thirdPartyAnswerView];
        [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_thirdPartyAnswerView]-38-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(_thirdPartyAnswerView)]];
    }
    [self.thirdPartyAnswerView configureViewForThirdPartyObject:object forViewStyle:TCThirdPartyAnswerViewStyleSearchCell];
}

Finalmente mi configuración de vista se ve así:

- (void) configureViewForThirdPartyObject:(TCTPOPlace *)object forViewStyle:(TCThirdPartyAnswerViewStyle) style {
    self.titleLabel.text = object.name;
    self.addressLabel.text = [NSString stringWithFormat:@"%@, %@, %@", object.address, object.city, object.state];
    self.ratingsLabel.text = [NSString stringWithFormat:@"%d Ratings", object.reviewCount];
    NSString *ratingImageName = [NSString stringWithFormat:@"yelp_star_rating_%.1f.png", object.rating];
    UIImage *ratingsImage = [UIImage imageNamed:ratingImageName];
    if (ratingsImage) {
        self.ratingImageView.image = ratingsImage;
    }
    if (object.imageUrl) {
        [self.thumbnailImageView setImageWithURL:[NSURL URLWithString:object.imageUrl] completed:nil];
    }
}
Una especie de solución, pero no entiendo por qué.Mi subvista fue diseñada a 320 de ancho, pero no tiene restricciones propias para el anchoLa subvista se agregó a la celda, pero con restricciones horizontales que se parecen a esto:@"|[_thirdPartyAnswerView]-38-|"La vista se configuró inmediatamente después de agregarse a la celda, lo que significa que el texto de la etiqueta de título se estableció en ese momento.Por la razón que sea, el texto se presentó como si la vista tuviera el 320 completo en lugar de 282.La etiqueta nunca se actualizó, aunque el marco de la subvista se actualizó a 282, y había restricciones en la etiqueta que la mantendrían correctamente dimensionada.Cambiar el tamaño de la vista en el xib para que sea 282 solucionó el problema, porque la etiqueta tiene el tamaño correcto para empezar.

Todavía no entiendo por qué la etiqueta no se vuelve a colocar después de que el tamaño de la vista principal se actualiza cuando tiene restricciones iniciales y finales.

Resuelto

Vea la respuesta de Matt a continuación:https://stackoverflow.com/a/15514707/287403

En caso de que no lea el comentario, el problema principal fue que, sin saberlo, estaba configurandopreferredMaxLayoutWidth a través de IB al diseñar una vista con un ancho mayor del que se mostraría (en algunos casos).preferredMaxLayoutWidth es lo que se utiliza para determinar dónde se ajusta el texto. Así que a pesar de que mi vista y titleLabel redimensionaron correctamente,preferredMaxLayoutWidth todavía estaba en el valor anterior, y provocaba un ajuste en puntos inesperados. Estableciendo el titleLabel a su tamaño automático (⌘ = en IB), y actualizandopreferredMaxLayoutWidth dinámicamente enlayoutSubviews antes de llamar super era la clave. Gracias mate

Respuestas a la pregunta(3)

Su respuesta a la pregunta