2010-06-03 14 views
35

Tengo una UIlabel en una UITableViewCell, que he creado mediante programación (es decir, no una punta o una subclase).UITableViewCell borra el fondo de la etiqueta cuando está resaltada

Cuando la celda se resalta (se pone azul) hace que todos los colores de fondo de los UILabels se vuelvan claros. Tengo 2 UILabels donde no quiero que este sea el caso. Actualmente estoy usando UIImageViews detrás de UILabel para que parezca que el color de fondo no cambia. Pero esta parece una forma ineficiente de hacerlo.

¿Cómo puedo detener el cambio del color de fondo de cierto UILabel cuando se resalta la UITableViewCell?

Respuesta

0

tuve que subclase el UITableView, crear una lista de etiquetas de la opinión de que yo quiero no hacer fondo transparente y anulación el método setHighlighted: animado: para restablecer el color de fondo de las etiquetas específicas. longwinding y fidely, si tan solo tuviera el código fuente t la clase real de UItableViewCell.

0

En mis aplicaciones tuve que cambiar el color azul del estilo de selección de uitableviewcell, así que tuve que configurar la visualización de uiimage, cuando hice clic en la celda se destacó como Imageview. Y eliminé el resaltado de la celda cuando volví a la vista. Y no pude entender tu problema claramente. Así se acaba de dar mi código y Prueba con esto,

cellForRowAtIndexPath Method: 

CGRect a=CGRectMake(0, 0, 300, 100); 
UIImageView *bImg=[[UIImageView alloc] initWithFrame:a]; 
bImg.image=[UIImage imageNamed:@"bg2.png"]; 
[bImg setContentMode:UIViewContentModeScaleToFill]; 
cell.selectedBackgroundView=bImg; 
[bImg release]; 


    -(void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:YES]; 

    NSIndexPath *deselect = [self.tableView indexPathForSelectedRow]; 
    [self.tableView deselectRowAtIndexPath:deselect animated:NO]; 

    } 

mejor de la suerte

38

Alternativamente subclase de la etiqueta que no quiere cambiar de color:

@interface PersistentBackgroundLabel : UILabel { 
} 

- (void)setPersistentBackgroundColor:(UIColor*)color; 

@end 


@implementation PersistentBackgroundLabel 

- (void)setPersistentBackgroundColor:(UIColor*)color { 
    super.backgroundColor = color; 
} 

- (void)setBackgroundColor:(UIColor *)color { 
    // do nothing - background color never changes 
} 

@end 

A continuación, establecer el color de una vez de forma explícita utilizando setPersistentBackgroundColor :. Esto evitará cambios de color de fondo desde cualquier lugar sin utilizar su método de cambio de color de fondo explícito personalizado.

Esto tiene la ventaja de eliminar también el fondo claro en la etiqueta durante las transiciones.

+1

Nunca pensé en eso, es una buena idea. Por el momento he subclasificado el UITableViewCell y he reemplazado el marcador y los métodos seleccionados para no cambiar el color de fondo de las subvistas seleccionadas, pero es un "hack" bastante desagradable –

+0

¿Alguien puede explicar cómo funciona esta subclase? ¿Dónde deberíamos poner este código? en la misma clase viewController o una clase separada? – raw3d

+4

Funciona como un encanto (y es uno de estos momentos de WTF en el desarrollo de iOS ...). –

3

Tengo el mismo problema y creo que es una especie de error de UIKit framework. Gracias a Dios, tengo una solución: ¡el orden importa! Sólo tienes que seguir la secuencia:

- (void)tableView:(UITableView *)t willDisplayCell:(UITableViewCell*)c forRowAtIndexPath:(NSIndexPath *)i { 
UIColor *bgc = [UIColor redColor]; 
// Set up the cell in following order: 
c.textLabel.backgroundColor = bgc; 
c.backgroundColor = bgc; 
c.textLabel.text = @"foo"; 
} 

No sé por qué, pero esta secuencia funciona bien y otra orden hace que parezca como si c.textLabel.backgroundColor se vio obligado a clearColor en algunas células después anulando su selección.

No fue un comportamiento aleatorio, sucedió la primera vez que se reutilizaron las células, no cuando se crearon, ni cuando se volvieron a utilizar. Con la solución, funciona bien siempre.

+0

Esto funcionó para mí también. No estoy seguro de por qué configurar la celda bg primero no funciona, pero cambiar la secuencia hizo una diferencia. –

-1

No pude obtener la respuesta aceptada para el trabajo; no es que yo piense que la respuesta es incorrecta (ni mucho menos, eso parece ser el Camino Correcto), pero mientras escribía mi primera aplicación iOS mi cabeza ya estaba girando con subclases. Así que decidí hacer trampa.

Digamos que la celda personalizada fue controlada por una clase TableViewCell. Creé un único archivo de píxel .png del color de fondo correcto y creé un objeto UIImageView en mi celda personalizada. Utilicé el inspector de Atributos para establecer la imagen por defecto y usé 'Escalar para rellenar'. Por un poco más atractivo visual, que luego añadió lo siguiente al tiempo de ejecución de atributos definidos por el usuario en el inspector de Identidad:

KeyPath    Type   Value 
layer.cornerRadius  Number  4 
layer.masksToBounds Boolean  YES 

Voilá, esquinas redondeadas en el barato.

Posicionado directamente detrás de UILabel, se ve el negocio, aunque obviamente no cambiará el tamaño del contenido (ya que el único contenido es su propia imagen). No es un problema para mí, ya que los datos que se muestran deben tener un tamaño fijo de todos modos.

En algunos valores que era bueno tener un color diferente, que se pueden ajustar con mucha facilidad:

cell.deviceDetailBackground.image = [UIImage imageNamed:@"detailBackground2.png"]; 

Donde 'célula' es la encarnación de mi celda personalizado en el método cellForRowAtIndexPath, creado usando TableViewCell *cell;. ¿No hay información para mostrar?

cell.deviceDetailBackground.image = nil; 

Estoy seguro de que habrá una buena razón por la que esto es una idea tonta, pero como yo estoy empezando con el desarrollo de iOS esto era una solución fácil que trabajó para mí. Siéntase libre de decirme por qué no hacerlo!

1

Acabo de crear un indicador en la subclase UILabel para deshabilitar el cambio de color de fondo después de awakeFromNib o init. Esto permite que el color inicial configurado en el guión gráfico surta efecto. Y no tenemos que llamar a ningún método adicional.

@implementation MWPersistentBGLabel { 
    BOOL disableBackgroundColorChange; 
} 

- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self setup]; 
    } 
    return self; 
} 

- (void)awakeFromNib { 
    [super awakeFromNib]; 
    [self setup]; 
} 

- (void)setup { 
    // disable background color change after setup is called 
    disableBackgroundColorChange = YES; 
} 

// if we ever have to change the color later on, we can do so with this method 
- (void)setPersistentBackgroundColor:(UIColor*)color { 
    [super setBackgroundColor:color]; 
} 

- (void)setBackgroundColor:(UIColor *)color { 
    if (!disableBackgroundColorChange) { 
     [super setBackgroundColor:color]; 
    } 
    // do nothing - background color never changes 
} 

@end 
41

Otra forma de mantener el color de fondo del cambio en punto a destacar es establecer la propiedad backgroundColor en la etiqueta de layer en lugar de en la propia etiqueta.

#import <QuartzCore/QuartzCore.h> 

...

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

    // Get a table cell 
    UITableViewCell *cell = [tableView dequeueReusableCellForIdentifier:@"cell"]; 

    // Set up the table cell 
    cell.textLabel.text = @"This is a table cell."; 

    // If you're targeting iOS 6, set the label's background color to clear 
    // This must be done BEFORE changing the layer's backgroundColor 
    cell.textLabel.backgroundColor = [UIColor clearColor]; 

    // Set layer background color 
    cell.textLabel.layer.backgroundColor = [UIColor blueColor].CGColor; 

    return cell; 
} 

El layer no se ve afectado por el resaltado celular o selección.

+1

Esta es una gran idea, pero no parece funcionar en iOS 6. Para iOS 7 en adelante, este debería ser el método preferido. Tenga en cuenta que layer.backgroundColor es un CGColor, por lo que necesitará 'cell.textLabel.layer.backgroundColor = [[UIColor blueColor] CGColor];' –

+2

@ColinTremblay: Buena captura en el 'CGColor', gracias. No tenía idea de que esto no funcionaba en iOS 6 ... al jugar en el simulador iOS 6.1 parece funcionar si ** primero ** estableces la propiedad 'backgroundColor' de' UILabel' en '[UIColor clearColor ] '. Extraño. Actualicé la respuesta para reflejar ambas correcciones. – Tommy

+0

Gran hallazgo. Esta es de lejos la mejor y más fácil solución. –

36

Necesitas subclase UITableViewCell y anular los dos métodos siguientes:

Objective-C:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated 
{ 
    UIColor *backgroundColor = self.myLabel.backgroundColor; 
    [super setHighlighted:highlighted animated:animated]; 
    self.myLabel.backgroundColor = backgroundColor; 
} 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
{ 
    UIColor *backgroundColor = self.myLabel.backgroundColor; 
    [super setSelected:selected animated:animated]; 
    self.myLabel.backgroundColor = backgroundColor; 
} 

Swift

override func setSelected(selected: Bool, animated: Bool) { 
    let color = self.myLabel.backgroundColor 
    super.setSelected(selected, animated: animated) 
    self.myLabel.backgroundColor = color 
} 

override func setHighlighted(highlighted: Bool, animated: Bool) { 
    let color = self.myLabel.backgroundColor 
    super.setHighlighted(highlighted, animated: animated) 
    self.myLabel.backgroundColor = color 
} 
+0

Esta es la mejor solución. Gracias –

4

puedo estar equivocado, pero yo no se pudo encontrar para anular directamente un getter/setter existente en Swift. Partiendo de la respuesta de user479821, encontré una solución alternativa que parece producir los resultados deseados. Agregué las anotaciones IBDesignable/IBInspectable en caso de que use el guión gráfico, que representa el color final en el editor.

@IBDesignable 
class PersistentBackgroundLabel: UILabel { 
    @IBInspectable var persistentBackgroundColor: UIColor = UIColor.clearColor() { 
    didSet { 
     super.backgroundColor = persistentBackgroundColor 
    } 
    } 

    override var backgroundColor: UIColor? { 
    didSet { 
     if backgroundColor != persistentBackgroundColor { 
      backgroundColor = persistentBackgroundColor 
     } 
    } 
    } 
} 
2

Establecer el color de fondo en label.layer.backgroundColor puede solucionarlo.

Parece que cell cambiará backgroundColor de UILabel al resaltar.

Cuestiones relacionadas