2009-07-26 11 views
13

J'ai ajouté une ombre de texte aux cellules dans mon UITableView pour leur donner un regard gravé:Suppression ombre du texte dans UITableViewCell quand il est sélectionné

cell.textLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.000]; 
cell.textLabel.shadowColor = [UIColor whiteColor]; 
cell.textLabel.shadowOffset = CGSizeMake(0, 1); 

Étant donné que la couleur de l'ombre est en fait blanc, quand une ligne obtient sélectionnée et devient bleu, l'ombre blanche devient vraiment visible et rend le texte moche.

Est-ce que quelqu'un sait comment je peux supprimer l'ombre avant que le style de sélection de cellule par défaut ne soit appliqué?

J'ai essayé:

  1. En utilisant -tableView:willSelectRowAtIndexPath: pour désinitialiser l'ombre avec cell.textLabel.shadowColor = nil mais cela ne fonctionne pas dans le temps - l'ombre se unset seulement après le style de sélection bleu est appliqué.
  2. Vérification cell.selected dans tableView:cellForRowAtIndexPath: avant de définir l'ombre, mais cela ne fonctionne évidemment pas puisque la cellule n'est pas redessinée après une sélection.

J'ai également essayé de remplacer la méthode déléguée -tableView:willDisplayCell:forRowAtIndexPath: comme Kevin suggéré ci-dessous. A partir des instructions de journalisation que j'ai placées, cette méthode de délégué n'est appelée que juste avant qu'une cellule ne soit dessinée - au moment où une cellule est touchée, il est déjà trop tard. C'est le code que j'ai utilisé

(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSLog(@"in willDisplayCell"); 
    if (cell.highlighted || cell.selected) { 
    NSLog(@"drawing highlighed or selected cell"); 
    cell.textLabel.shadowColor = nil; 
    } else { 
    cell.textLabel.shadowColor = [UIColor whiteColor]; 
    } 
} 

Répondre

35

Une méthode qui devrait fonctionner est d'étendre UITableViewCell et de surcharger les méthodes setSelected et setHighlighted, en définissant l'état d'ombre portée en conséquence. Cela s'assurera qu'il est peint en même temps que la mise à jour en surbrillance en arrière-plan.

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated 
{ 
    [super setHighlighted:highlighted animated:animated]; 
    [self applyLabelDropShadow:!highlighted]; 
} 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
{ 
    [super setSelected:selected animated:animated]; 
    [self applyLabelDropShadow:!selected]; 
} 

- (void)applyLabelDropShadow:(BOOL)applyDropShadow 
{ 
    self.textLabel.shadowColor = applyDropShadow ? [UIColor whiteColor] : nil; 
} 
+0

En fait, il se peut que vous ayez juste besoin de surcharger setHighlighted: animé et ne pas toucher setSelected: animé du tout. Je vais essayer ça en premier. –

+0

Merci Mike! Cela fonctionne parfaitement. –

+3

Je peux confirmer que vous devez remplacer les deux. La cellule est mise en évidence lorsque vous la touchez, puis sélectionnée lorsque vous levez le doigt vers le haut. Si vous remplacez uniquement setHighlighted:, l'ombre réapparaît lorsque le toucher se termine.Même si vous passez à une autre vue après la sélection, c'est visible. – benzado

3

Utilisez -tableView:willDisplayCell:forRowAtIndexPath:. C'est la dernière chose qui est appelée juste avant que la cellule ne soit affichée, vous pouvez donc interroger sa propriété selected et définir l'ombre du texte en conséquence.

+2

Merci Kevin. J'ai lu la documentation sur ceci une fois que vous avez pointé '-tableView: willDisplayCell: forRowAtIndexPath:' out, et il semble que ça devrait faire l'affaire, mais ce n'est pas le cas. Je pense que '-tableView: willDisplayCell: forRowAtIndexPath:' est appelé quand la cellule est dessinée en premier, et au moment où une cellule est touchée, elle a déjà été dessinée et ainsi la méthode delegate n'est pas appelée. Je vais mettre à jour ma question avec le code que j'ai essayé. Merci encore! –

+1

Ok, je pense que la solution correcte est de créer votre propre sous-classe UITableViewCell et de surcharger '-setSelected: animated:' pour ajuster l'ombre si nécessaire. –

3

Vous devez remplacer tableView:willDisplayCell:forRowAtIndexPath: et vous devez régler la backgroundColor-[UIColor clearColor], aussi, vous ne devez agir sur l'état mis en surbrillance, l'état sélectionné a une signification légèrement différente

2

Je pense que cela vaut mieux:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated 
{ 
    [super setHighlighted:highlighted animated:animated]; 
    [self applyLabelDropShadow:!self.highlighted]; 
} 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
{ 
    [super setSelected:selected animated:animated]; 
    [self applyLabelDropShadow:!self.selected]; 
} 

Il n'y aura pas d'ombre lors des changements entre les états.

Questions connexes