J'ai une construction simple tableViewCell dans le constructeur d'interface . Elle contient un UIView qui contient une image . Maintenant, lorsque je sélectionne la cellule, l'arrière-plan de sélection bleu par défaut est affiché, mais la couleur d'arrière-plan de mon UIView a disparu.
Le fichier d'implémentation de mon UITableViewCell ne fait rien de spécial. Il suffit d'init & retourne soi-même et tout ce que je fais dans setSelected est super appel.
Comment puis-je obtenir mon backgroundColor UIView à afficher lorsque la tableView est sélectionnée?
Le problème ici est que la [super] mise en œuvre de
- (void) setSelected:(BOOL) selected animated:(BOOL) animated;
définit toutes les couleurs d'arrière-plan de UITableViewCell sur rgba (0,0,0,0). Pourquoi? Peut-être pour nous faire tous transpirer?
Ce n'est pas que des vues entières disparaissent (comme le montre le fait que si vous modifiez les propriétés de la bordure du calque des vues, celles-ci sont conservées).
Voici la séquence des appels de fonction résultant du contact avec une cellule
Donc, vos options sont de
Malheureusement, réaffirmer les couleurs d'arrière-plan dans setHighlighted ne fait rien car setHighlighted est appelé avant que toutes les couleurs d'arrière-plan ne soient définies sur [r: 0 b: 0 g: 0 a: 0] lors du premier appel à setSelected.
// TODO: Donnez une excellente description de la façon de remplacer setSelected (restez à l'écoute)
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
UIColor *backgroundColor = self.channelImageView.backgroundColor;
[super setHighlighted:highlighted animated:animated];
self.channelImageView.backgroundColor = backgroundColor;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
UIColor *backgroundColor = self.channelImageView.backgroundColor;
[super setSelected:selected animated:animated];
self.channelImageView.backgroundColor = backgroundColor;
}
Auparavant, j'ai fait comme @ P5ycH0 a dit (image 1x1 étirée), mais après @Brooks, je me suis dit que remplacer -(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
dans mon implémentation UITableViewCell
personnalisée et réinitialiser les couleurs d'arrière-plan après avoir appelé [super setHighlighted:highlighted animated:animated];
garde mes couleurs d'arrière-plan lorsque la cellule est sélectionnée
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
myView.backgroundColor = myColor;
}
Lorsque votre UITableViewCell
est sélectionné, vous devez prêter attention à deux états: Highlighted
et Selected
.
Ainsi, pour les scénarios où vous avez une classe de cellule personnalisée qui est la sous-classe de UITableViewCell
, vous pouvez facilement remplacer ces deux méthodes pour éviter cette situation (Swift):
class MyCell: UITableViewCell {
@IBOutlet var myView: UIView!
override func setHighlighted(highlighted: Bool, animated: Bool) {
let myViewBackgroundColor = myView.backgroundColor
super.setHighlighted(highlighted, animated: animated)
myView.backgroundColor = myViewBackgroundColor
}
override func setSelected(selected: Bool, animated: Bool) {
let myViewBackgroundColor = myView.backgroundColor
super.setSelected(selected, animated: animated)
myView.backgroundColor = myViewBackgroundColor
}
}
Brooks a une bonne explication à cela, mais je pense avoir une meilleure solution.
Dans votre sous-vue, remplacez setBackgroundColor:
par la couleur de votre choix. Le passeur sera toujours appelé, mais seule la couleur spécifiée sera appliquée.
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:[UIColor whiteColor]];
}
Vous devez remplacer les deux méthodes suivantes dans votre cellule personnalisée:
- (void) setSelected:(BOOL)selected animated:(BOOL)animated;
- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated;
Notez que:
[super setSelected:animated:]
et [super setHighlighted:animated:]
au début de votre implémentation personnalisée ou de vos méthodes correspondantes;UITableViewCellSelectionStyleNone
selectionStyle pour votre cellule personnalisée, afin de désactiver tout style UITableViewCell
par défaut;Voici l'exemple de la mise en oeuvre:
- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
[self setHighlightedSelected:highlighted animated:animated];
}
- (void) setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self setHighlightedSelected:selected animated:animated];
}
- (void) setHighlightedSelected:(BOOL)selected animated:(BOOL)animated
{
void(^selection_block)(void) =
^
{
self.contentView.backgroundColor = selected ? SELECTED_BACKGROUND_COLOR : NORMAL_BACKGROUND_COLOR;
};
if(animated)
{
[UIView animateWithDuration:SELECTION_ANIMATION_DURATION
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:selection_block
completion:NULL];
}
else
selection_block();
}
contentView
est la propriété de UITableViewCell
qui apparaît dans iOS 7. Notez que vous pouvez utiliser la ou les vues enfant de votre propre cellule à la place.
Ce problème peut (enfin) être résolu dans iOS 13. Trouvez ce joli paragraphe dans les notes de publication d'iOS 13 beta 3.
La classe UITableViewCell ne modifie plus les propriétés backgroundColor ou isOpaque de contentView ni aucune de ses sous-vues lorsque les cellules sont mises en surbrillance ou sélectionnées. Si vous définissez une couleur d'arrière-plan opaque sur une sous-vue de la cellule à l'intérieur (et y compris) de contentView, l'apparence à laquelle la cellule est mise en surbrillance ou sélectionnée peut être affectée. Le moyen le plus simple de résoudre tout problème avec vos sous-vues est de s'assurer que leur propriété backgroundColor est définie sur nil ou sur clear et que leur propriété opaque est définie sur false. Toutefois, si nécessaire, vous pouvez remplacer les méthodes setHighlighted (: animated :) et setSelected (: animated :) pour modifier manuellement ces propriétés dans vos sous-vues lors du déplacement. vers ou depuis les états en surbrillance et sélectionnés. (13955336)
Ok, perdre la couleur d’arrière-plan d’une classe UIView est un comportement normal quand il se trouve dans une tableviewcell sélectionnée. pixel blanc 1x1 étiré . Moche imo, mais cela fonctionne.
En rapport avec la réponse de @ Brooks, voici ce que j'ai fait pour que cela fonctionne dans Swift et iOS8/iOS9.
setSelected
et setHighlighted
contentView.backgroundColor
, car il ne doit pas nécessairement s’étendre sur toute la largeur de la cellule (accessoires).Utilisez le backgroundColor
de la cellule elle-même et réglez-le en conséquence.
class AwesomeTableViewCell: UITableViewCell {
private struct Constants {
static var highlightedColor = UIColor.greenColor()
static var selectedColor = UIColor.redColor()
static let animationTime = NSTimeInterval(0.2)
}
override func awakeFromNib() {
super.awakeFromNib()
contentView.backgroundColor = UIColor.clearColor()
backgroundColor = AppContext.sharedInstance.theme.colors.background
}
override func setHighlighted(highlighted: Bool, animated: Bool) {
if animated {
UIView.animateWithDuration(Constants.animationTime, animations: { () -> Void in
self.setHighlighted(highlighted)
})
} else {
self.setHighlighted(highlighted)
}
}
override func setSelected(selected: Bool, animated: Bool) {
if animated {
UIView.animateWithDuration(Constants.animationTime, animations: { () -> Void in
self.setSelected(selected)
})
} else {
self.setSelected(selected)
}
}
private func setHighlighted(highlighted: Bool) {
backgroundColor = highlighted ? Constants.highlightedColor : UIColor.whiteColor()
}
private func setSelected(selected: Bool) {
backgroundColor = selected ? Constants.selectedColor : UIColor.whiteColor()
}
}
Ajoutez ceci à votre UITableViewCell
override func setHighlighted(highlighted: Bool, animated: Bool) {
super.setHighlighted(false, animated: animated)
if highlighted {
self.backgroundColor = UIColor.blueColor()
}else{
UIView.animateWithDuration(0.2, animations: {
self.backgroundColor = UIColor.clearColor()
})
}
}
Je viens de passer un peu de temps sur cette question étrange. Je ne voulais pas définir le style UITableViewCellSelectionStyleNone pour conserver l'animation Nice lors de la sélection de ma ligne. Mais aucune des idées suggérées ne fonctionnait pour moi - j'essayais de remplacer setSelected et setHighlighted et de placer ma sous-vue backgroundColor ici - la réinitialisation continuelle par iOS et le clignotement (nouvelle couleur -> ancienne couleur) . Pour moi, le correctif était assez simple . Lorsque ma ligne est sélectionnée, un autre contrôleur de vue est poussé, l'utilisateur choisit une option sur cet écran et le délégué est appelé lorsque je change de couleur en fonction de la sélection de l'utilisateur. Dans ce délégué, je viens de faire [cellule setSelected: NO animated: NO] pour ma cellule. (J'ai statique UITableViewController et des sorties vers les cellules) . Vous pouvez probablement désélectionner une cellule dans la méthode didSelect, mais dans mon cas, j'utilise des légendes.
Voici mon point de vue là-dessus. J'ai une sous-classe dont toute ma cellule hérite, c'est donc comme cela que je le fais pour éviter le changement d'arrière-plan dans mes UIImageViews:
override func setHighlighted(highlighted: Bool, animated: Bool) {
var backgroundColors = [UIView: UIColor]()
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
backgroundColors[imageView] = imageView.backgroundColor
}
}
super.setHighlighted(highlighted, animated: animated)
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
imageView.backgroundColor = backgroundColors[imageView]
}
}
}
override func setSelected(selected: Bool, animated: Bool) {
var backgroundColors = [UIView: UIColor]()
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
backgroundColors[imageView] = imageView.backgroundColor
}
}
super.setSelected(selected, animated: animated)
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
imageView.backgroundColor = backgroundColors[imageView]
}
}
}
Cela corrige automatiquement le problème pour tous les UIImageView
.
Dans iOS 7, ce qui a fonctionné pour moi est de remplacer setSelected:animated:
dans la sous-classe UITableViewCell
, mais contrairement à la suggestion de @Brooks, j'ai appelé [super setSelected:selected animated:animated]
.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Reassert the background color of the color view so that it shows
// even when the cell is highlighted for selection.
self.colorView.backgroundColor = [UIColor blueColor];
}
Cela me permet de conserver l'animation de sélection par défaut du système lorsque l'utilisateur appuie sur la cellule et de la désélectionner dans la colonne didSelectRowAtIndexPath:
du délégué de la vue de table.
Vous pouvez modifier le comportement de tableViewCell en remplaçant la fonction setHighlighted dans la classe UITableViewCell (vous devrez en hériter). Exemple de code dans lequel je change l'image de fond de ma cellule:
// animate between regular and highlighted state
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated; {
[super setHighlighted:highlighted animated:animated];
//Set the correct background Image
UIImageView* backgroundPicture = (UIImageView*)[self viewWithTag:HACK_BACKGROUND_VIEW_TAG];
if (highlighted) {
backgroundPicture.image = [UIImage imageNamed:@"FondSelected.png"];
}
else {
backgroundPicture.image = [UIImage imageNamed:@"Fond.png"];
}
}
Vous pouvez également modifier le mode de sélection en gris, bleu ou aucun dans le générateur d'interface.
A partir de là, vous avez dit que vous avez construit une tableViewCell en utilisant IB. J'aimerais vérifier si vous ajoutez votre vue en tant que sous-vue de contentView
de UITableViewCell, et non de view
. La vue du contenu est la vue par défaut du contenu affiché par la cellule.
De la référence:
La vue du contenu d'un objet UITableViewCell est la vue d'ensemble par défaut du contenu affiché par la cellule. Si vous souhaitez personnaliser des cellules en ajoutant simplement des vues supplémentaires, vous devez les ajouter à la vue du contenu afin qu'elles soient correctement positionnées lorsque la cellule passe en mode édition et en sort.
Swift 4
Dans votre classe UITableViewCell:
override func setSelected(_ selected: Bool, animated: Bool) {
myView.backgroundColor = UIColor.blue
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
myView.backgroundColor = UIColor.blue
}