2010-08-20 5 views
6

Estoy tratando de hacer una UITableViewCell subclasificada donde dibujo una imagen en la esquina superior derecha. Lo tengo funcionando perfectamente, excepto cuando configuro self.backgroundView, mi imagen de fondo cubre la imagen dibujada en drawRect.subclassed UITableViewCell - backgroundView cubre todo lo que hago en drawRect

Debe haber una manera de poder establecer una imagen de fondo (y el seleccionadoBackgroundView) sin cubrir lo que se está haciendo en drawRect.

¿Voy por esto de la manera incorrecta?

EDIT: He publicado un example project with the problem.

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 

    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { 

    // TODO: figure out why this covers up self.starImage that's drawn in drawRect 
     self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]] autorelease]; 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect { 
    [self.starImage drawAtPoint:CGPointMake(self.bounds.size.width - self.starImage.size.width, 0.0)]; 
} 

EDIT 2: a petición del AWrightIV, así es como lo tengo trabajo ... que no requirió la subclasificación UITableViewCell en absoluto. Sólo estoy añadiendo una vista secundaria a cell.backgroundView:

// create a UIImageView that contains the background image for the cell 
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]]; 

// create another UIImageView that contains the corner image 
UIImage *starRedImage = [UIImage imageNamed:@"starcorner_red.png"]; 
UIImageView *starImageView = [[UIImageView alloc] initWithFrame:CGRectMake(297, 
                       0, 
                       starRedImage.size.width, 
                       starRedImage.size.height)]; 
starImageView.image = starRedImage; 

// add the corner UIImageView as a subview to the background UIImageView 
[bgImageView addSubview:starImageView]; 

// set cell.background to use the background UIImageView 
cell.backgroundView = bgImageView; 

Respuesta

9

Realmente no se supone que mezcle el dibujo con su celda de esa manera, está operando en un nivel inferior al que está funcionando la maquinaria UITableViewCell, y es por eso que obtiene este problema.

Este es solo uno de los diversos problemas que acabará encontrando. Te encontrarás con otros problemas a medida que avanzas por ese camino, incluidos problemas con la forma en que funciona la selección.

El enfoque correcto es crear una UIView personalizada que contenga el código para dibujar, y luego puede agregarSubView en la vista raíz de su celda. Eso se encargará de la representación en el orden correcto, y no interferirá con el sistema de selección, y funcionará correctamente en este caso.

+0

Por "vista de raíz de la celda", ¿te refieres a cell.contentView? Cuando he probado una UIView personalizada (o UIImageView) tengo problemas con el botón eliminar de la celda que empuja la vista hacia la izquierda. Estoy usando UIViewAutoresizingFlexibleLeftMargin en la vista personalizada, ya que estoy tratando de admitir el modo horizontal, y quiero que la imagen de la esquina de la estrella siempre se fije en la esquina superior derecha de la celda. (Además, necesito apoyar el modo de edición y el reordenamiento). –

+0

Asegúrese de que su vista sea compatible con el protocolo de cambio de tamaño implementando el método layoutSubviews de la clase UIView. Este método se invocará con el nuevo tamaño si la UI gira, o si se está editando. Simplemente ajuste los límites de las subvistas o marcos allí. –

+0

Descubrí cómo hacerlo sin crear subclases de UITableViewCell. Todo lo que necesitaba era crear un ImageView con la estrella, luego agregar eso como una subvista a un ImageView con la imagen de fondo de la celda, y finalmente asignar eso a mi cell.backgroundView (no a contentView). Entonces, gracias a Ben por alejarme de la solución drawRect y señalarme en la dirección correcta. Aprendí mucho, y ahora parece fácil en retrospectiva. –

1

¿Ha intentado añadir un [super drawRect:rect]; allí?

+0

Acabo de intentar agregarlo, pero no tuvo ningún efecto. Aunque aprecio la sugerencia. –

4

No debe anular el -drawRect: de una celda de tabla. En su lugar, cree una nueva vista personalizada y agréguela al contentView de la celda y dibuje allí.

+0

El problema al hacer eso, es si deslizo para eliminar la celda, el botón eliminar empuja mi imagen de "esquina de estrella" a la izquierda, por lo que terminé tratando de usar drawRect. Sin embargo, jugaré un poco más con eso, en caso de que me haya perdido algo. Gracias. –

-2

Aquí hay una solución que es un poco complicada, pero se ajusta exactamente a mis requisitos ... con un defecto fatal: cuando las células se reutilizan, la esquina de la estrella aparece cuando yo no quiero.

http://dl.dropbox.com/u/2349787/UIImage_Position_subclassed_cell2.zip

Todavía estoy usando drawRect aquí, pero sólo porque self.starImage es nulo si se accede a él dentro del método initWithStyle. Además, en lugar de agregar la subvista a self.contentView, la agrego a self.backgroundView para evitar que el botón de eliminación de la celda interfiera con ella. La esquina de la estrella está posicionada correctamente tanto en modo vertical como horizontal, y también funciona bien en el modo de edición.

Sin embargo, con el problema de la reutilización de la celda, sigue siendo un no ir ... entonces, tal vez estoy de regreso tratando de hacerlo sin subclasificar UITableViewCell.

Estoy abierto a cualquier sugerencia. ¡Gracias!

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { 
     // Initialization code 

     self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]] autorelease]; 
    } 
    return self; 
} 

- (void) drawRect:(CGRect)rect { 

    UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(self.bounds.size.width - self.starImage.size.width, 0, self.starImage.size.width, self.starImage.size.height)] autorelease]; 
    imageView.image = self.starImage; 
    imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; 

    [self.backgroundView addSubview:imageView]; 
} 
+4

Llamar a 'addSubview:' inside 'drawRect:' no es una buena idea porque 'drawRect:' se llamará varias veces. – 0xced

Cuestiones relacionadas