2010-07-28 9 views
9

De forma predeterminada, una instancia de UITableViewCell coloca el par de etiquetas textLabel/detailTextLabel en el centro de su vista principal. Prefiero tener el par alineado a la parte superior de la celda. ¿Cómo hago eso programáticamente?UITableViewCell. ¿Cómo alineo textLaText al top?

Gracias,
Doug

+0

¿Esta es una pregunta relacionada con el Iphone? –

+0

Sí. UITableViewCell junto con UITableView y UITableViewController son exclusivos del iPhone OS. ¿No? – dugla

+1

Entonces, ¿por qué la pregunta no está etiquetada como iphone? Tenga cuidado al etiquetar, para que otros puedan beneficiarse de sus preguntas. –

Respuesta

24

Los documentos describen - [UIView layoutSubviews] como

"Overridden by subclasses to layout subviews when layoutIfNeeded is invoked. The default implementation of this method does nothing." 

Esa descripción no está detalles, pero es preciso. En este caso, el comportamiento del método es diseñar sus subvistas. Se invocará cada vez que cambie la orientación del dispositivo. También está programado para una invocación posterior siempre que llame a -setNeedsLayout.

Dado que la implementación de UIView no hace nada, (y supongo que lo mismo para UIControl), obtiene total libertad creativa para hacer que sus subvistas de subclase UIView se ubiquen donde usted las desee.

En la subclasificación un UITableViewCell, que tienen un par de opciones para tratar:

  1. -layoutSubviews override y
    1. manipular la posición de la incorporada en el textLabel y vistas -detailLabel.
  2. Anulación -viewDidLoad,
    1. crear dos de sus propios UILabels para proporcionar el texto y el texto detallado,
    2. añadirlos a self.contentView y
    3. -layoutSubviews de anulación para manipular la posición de su encargo UILabel ve

En un related SO question, el reco La recomendación es evitar el # 1, manipulando el texto incorporado LabelLabel y detailTextLabel.

Una apuesta más fiable sería hacer algo como esto:


@interface MyTableViewCell : UITableViewCell { 
    UILabel *myTextLabel; 
    UILabel *myDetailTextLabel; 
} 
// ... property declarations 
@end 

@implementation MyTableViewCell 
@synthesize myTextLabel, myDetailTextLabel; 

- (id) initWithFrame: (CGRect)frame { 
    self = [super initWithFrame: frame]; 
    if (self) { 
     myTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 
     [self.contentView addSubview: myTextLabel]; 

     myDetailTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 
     [self.contentView addSubview: myDetailTextLabel]; 
    } 
    return self; 
} 

- (void) dealloc { 
    [myTextLabel release]; 
    [myDetailTextLabel release]; 
    [super dealloc]; 
} 

- (void) layoutSubviews { 

    // Let the super class UITableViewCell do whatever layout it wants. 
    // Just don't use the built-in textLabel or detailTextLabel properties 
    [super layoutSubviews]; 

    // Now do the layout of your custom views 

    // Let the labels size themselves to accommodate their text 
    [myTextLabel sizeToFit]; 
    [myDetailTextLabel sizeToFit]; 

    // Position the labels at the top of the table cell 
    CGRect newFrame = myTextLabel.frame; 
    newFrame.origin.x = CGRectGetMinX (self.contentView.bounds); 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [myTextLabel setFrame: newFrame]; 

    // Put the detail text label immediately to the right 
     // w/10 pixel gap between them 
    newFrame = myDetailTextLabel.frame; 
    newFrame.origin.x = CGRectGetMaxX (myTextLabel.frame) + 10.; 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [myDetailTextLabel setFrame: newFrame]; 
} 

@end 

En MyTableViewCell, que sería ignorar las etiquetas de texto incorporados y utilizar sus propios UILabels personalizados. Usted toma el control completo de colocarlos dentro del contenido de la celda de la vista de tabla.

Voy a dejar un montón de cosas. Al hacer un diseño personalizado con etiquetas de texto, le recomendamos considerar:

  • Calculando su propio algoritmo de diseño.

    Estoy utilizando un algoritmo de diseño anterior que cambia el tamaño de los UILabels personalizados para que se ajusten a su contenido de texto, y luego los coloca uno al lado del otro. Es probable que desee algo más específico para su aplicación.

  • Manteniendo las etiquetas personalizadas dentro de la vista de contenido.

    En -layoutSubviews, es posible que desee que la lógica mantenga los UILabels personalizados dimensionados y colocados de modo que no queden fuera de los límites del contenido rect. Con mi ingenua lógica de diseño, cualquier texto largo insertado en UILabel (o en ambos) podría hacer que las etiquetas se posicionen directamente fuera de los límites de la vista de contenido.

  • Cómo manejar -viewDidLoad/-viewDidUnload.

    Como se ha indicado anteriormente, esta subclase no controla la carga desde un plumín. Es posible que desee utilizar IB a la disposición de su celda, y si lo hace, tendrá que pensar en -viewDidLoad/-viewDidUnload/-initWithCoder:

+0

Gracias por la iluminación súper profunda de layoutSubviews. No tenía idea de que era tan fácil de usar. Guay. – dugla

+0

Excelente respuesta, pero creo que debería reescribir el initWithStyle: reuseIdentifier: en lugar del método initWithFrame :. – Rodrigo

+1

No estoy seguro de que haya una gran ventaja al anular 'initWithStyle: reuseIdentifier:' vs 'initWithFrame'. Sobre todo porque el reuseIdentifier se puede establecer explícitamente después de la inicialización. Para las subclases UITableViewCell, tal vez un -initWithReuseIdentifier: sería un inicializador designado más conveniente. Para las subclases de celda, ignorar la propiedad 'style'/dejar que tome el valor predeterminado parece la mejor práctica. Dicho esto, podrías definir tu propia constante de estilo. ¿Pero quién lo usaría? –

0

diseño de la UITableViewCell textLabel y detailTextLabel no son directamente modificables, excepto al decantarse por una de las formas que se indican proporcionados por la API.

typedef enum { 
    UITableViewCellStyleDefault, 
    UITableViewCellStyleValue1, 
    UITableViewCellStyleValue2, 
    UITableViewCellStyleSubtitle 
} UITableViewCellStyle; 

Si desea personalizar el diseño UITableViewCell, tendrá que hacerla una subclase y sobreescribir el método -layoutSubviews.


- (void) layoutSubviews { 
    // [super layoutSubViews]; // don't invoke super 

    ... do your own layout logic here 
} 
+0

layoutSubviews es un método que nunca he anulado y está poco documentado. Podrías elaborar un poco? Gracias. – dugla

2

El siguiente método en la subclase debe UITableViewCell forma rápida y concisa alinee textLabel y detailTextLabel en la parte superior de la celda (asiente con la cabeza al código de Bill), sin agregar ninguna vista personalizada.

- (void) layoutSubviews 
{ 
    [super layoutSubviews]; 

    // Set top of textLabel to top of cell 
    CGRect newFrame = self.textLabel.frame; 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [self.textLabel setFrame:newFrame]; 

    // Set top of detailTextLabel to bottom of textLabel 
    newFrame = self.detailTextLabel.frame; 
    newFrame.origin.y = CGRectGetMaxY (self.textLabel.frame); 
    [self.detailTextLabel setFrame:newFrame]; 
} 
Cuestiones relacionadas