37 votes

Impossible de modifier la couleur d'arrière-plan d'une cellule d'un tableau statique sous iOS 7 (iPad)

Je ne parviens pas à modifier la couleur d'arrière-plan des UITableViewCells statiques sous iOS 7, lorsqu'elles sont exécutées sur un appareil iPad. Vous pouvez facilement vérifier cela avec la configuration suivante :

  • Créez un nouveau projet universel dans Xcode 5 avec deux storyboards.
  • Dans chaque storyboard, mettez un seul contrôleur - le contrôleur de la vue de la table, et définissez-le comme le contrôleur initial.
  • Mettez quelques (par exemple 3) cellules statiques dans la vue tableau dans les deux contrôleurs/storyboards.
  • Définissez la couleur d'arrière-plan de chaque cellule statique à différentes couleurs dans Interface Builder (j'utilise les couleurs rouge, verte et claire).

Maintenant, exécutez l'application sur les simulateurs iPhone et iPad (iOS 7).

Sur le simulateur de l'iPhone, tout est ok ;
tandis que sur le simulateur iPad, toutes les cellules sont colorées en blanc.

J'ai essayé de forcer l'iPad à fonctionner correctement en définissant les propriétés d'exécution dans Interface Builder pour les cellules :

  • backgroundColor à la couleur claire
  • contentView.backgroundColor à la couleur claire
  • backgroundView à zéro

mais rien n'y fait. En fait, en définissant la propriété runtime de contentView.backgroundColor changera la couleur de la cellule, mais cela ne fonctionne pas avec une couleur claire (ce qui signifie qu'il y a une autre vue colorée en blanc derrière elle).

Il est très étrange que deux appareils équipés de la même version d'iOS produisent des résultats différents. Quelqu'un d'autre peut-il confirmer ce bug ?

Quelqu'un a-t-il une solution à ce problème, ou la seule façon de procéder est d'opter pour les propriétés dynamiques + le réglage de la couleur dans l'espace de travail ? cellForRowAtIndexPath ? Je voudrais utiliser des cellules statiques, car la nature du problème est statique.

p.s. Je viens de me rendre compte que j'ai oublié d'essayer de régler la backgroundView.backgroundColor propriété d'exécution pour effacer la couleur, et je n'ai pas accès à un Mac pour le moment. Peut-être que cela ferait l'affaire.

0 votes

J'ai essayé de changer la couleur de fond de la vue du contenu de chaque tableViewCell statique pour ipad dans le storyboard, cela fonctionne, mais pas POURQUOI ?

0 votes

Réglez-le sur une couleur claire (et la couleur de fond de la table sur une couleur aléatoire, par exemple le violet), et vous verrez que cela ne fonctionne pas (la cellule sera blanche).

0 votes

J'ai exactement le même problème, sur mon Iphone 4s avec ios 7 cela fonctionne parfaitement, mais sur mon Ipad avec ios 7 les cellules sont blanches, et je n'utilise même pas de la couleur claire mais une couleur unie.

57voto

fabrizotus Points 611

Faites-le :

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
     UIImage *pattern = [UIImage imageNamed:@"image.png"];
     [cell setBackgroundColor:[UIColor colorWithPatternImage:pattern]];  
}

Fonctionne pour moi sur IOS7

1 votes

...et cette méthode serait l'endroit approprié pour finaliser une cellule en cours d'exécution depuis iOS2.

0 votes

C'est la seule solution qui fonctionne pour l'instant. J'espérais trouver une solution dans IB (sans aucun code, comme nous pouvions le faire avant iOS7), mais il semble qu'il n'y ait pas de solution de ce type pour le moment, et nous devrons attendre qu'Apple règle ce problème. Je vais accepter cette solution, même si elle n'est pas exactement ce que je recherchais, comme une solution de contournement temporaire. Mais je veux ajouter quelques avertissements : si vous utilisez cette solution avec des cellules statiques, vous devez sous-classer UITableViewController et surcharger UNIQUEMENT les méthodes déléguées (dans ce cas willDisplayCell). Vous ne devez pas surcharger les méthodes de la source de données lorsque vous utilisez des cellules statiques.

0 votes

Vous ne pouvez pas utiliser le UIViewController standard avec un tableau intégré, car les cellules statiques nécessitent le UITableViewController pour fonctionner correctement.

10voto

Chex Points 41

Selon Le document d'Apple :

Que vous utilisiez une cellule prédéfinie ou personnalisée, vous pouvez modifier l'arrière-plan de la cellule à l'aide de la commande backgroundView ou en modifiant la propriété héritée backgroundColor propriété. Dans iOS 7, les cellules ont un arrière-plan blanc par défaut ; dans les versions antérieures d'iOS, les cellules héritent de la couleur d'arrière-plan de la vue tableau qui les entoure. Si vous souhaitez modifier la couleur d'arrière-plan d'une cellule, faites-le dans la propriété tableView:willDisplayCell:forRowAtIndexPath: de votre délégué de la vue de la table.

Donc peu importe la couleur que vous mettez dans tableView:cellForRowAtIndexPath: L'iOS 7 l'a changé en blanc plus tard. Il suffit de le définir dans tableView:willDisplayCell:forRowAtIndexPath: . Cela a parfaitement fonctionné pour moi.

2 votes

Je pense que la dernière ligne du texte cité de la docs n'était pas là quand cette question a été postée. J'ai été informé par Apple via le Bug Reporter qu'ils sont conscients du problème. Je ne suis pas le premier à l'avoir signalé (mon problème était un doublon d'un autre problème qui n'est toujours pas résolu). Je suppose qu'ils ont ajouté la ligne ci-dessus dans la documentation pour donner aux gens une solution programmatique à ce problème avant qu'ils ne résolvent le problème de l'IB. La couleur par défaut ne devrait être que cela - par défaut si vous ne définissez pas d'autres valeurs.

1 votes

Le comportement est, au mieux, incroyablement incohérent : La couleur d'arrière-plan de l'IB apparaît sur les iPhones, mais pas sur les iPads. Le recours à un réglage programmé backgroundColor sur tableView:willDisplayCell:forRowAtIndexPath: n'est rien d'autre qu'un affreux piratage.

2voto

David Points 136

La seule façon de résoudre ce problème était de créer le tableau par programme au lieu d'utiliser le storyboard. Pour référence, je vais poster ma solution, j'espère qu'elle pourra aider quelqu'un.

J'ai remplacé le uitableviewcontroller par un uiviewcontroller.

puis a ajouté ceci :

le fichier d'en-tête

#import <UIKit/UIKit.h>

@interface LtHomeViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
NSArray *mFiles;
NSArray *mPics;
}

@end

Et le fichier du module

#import "LtHomeViewController.h"
#import "LtHomeToolbar.h"
#import "LtHomeCustomCell.h"

@interface LtHomeViewController () <LtHomeToolbarDelegate>

@end

@implementation LtHomeViewController
{
LtHomeToolbar *mainToolbar;
UITableView *theListView;
}

#define TOOLBAR_HEIGHT 64.0f

-(UIStatusBarStyle)preferredStatusBarStyle{
 return UIStatusBarStyleLightContent;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

CGRect toolbarRect = self.view.bounds; // View controller's view bounds
toolbarRect.size.height = TOOLBAR_HEIGHT;

mainToolbar = [[LtHomeToolbar alloc] initWithFrame:toolbarRect]; // At top
mainToolbar.delegate = self;

[self.view addSubview:mainToolbar];

//
mFiles = [[NSArray alloc] initWithObjects:@"../Lumina.app/lumina0.pdf", @"../Lumina.app/lumina8.pdf", @"../Lumina.app/lumina9.pdf", @"../Lumina.app/lumina10.pdf", nil];
mPics = [[NSArray alloc] initWithObjects:@"vol0.jpg", @"vol8.jpg", @"vol9.jpg", @"vol10.jpg", nil];
//
CGRect tableViewFrame = self.view.bounds;
tableViewFrame.origin.y = TOOLBAR_HEIGHT;
tableViewFrame.size.height = self.view.bounds.size.height - TOOLBAR_HEIGHT;

theListView = [[UITableView alloc] initWithFrame:tableViewFrame style:UITableViewStylePlain];
theListView.delegate = self;
theListView.dataSource = self;

theListView.backgroundColor = [UIColor colorWithRed:(116/255.0) green:(167/255.0) blue:(179/255.0) alpha:1.0];

[self.view addSubview:theListView];
}

#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView
{
   return 1;
}

- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
   return [mFiles count];
}

- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   static NSString *cellIdentifier = @"HomeCell";

   // Similar to UITableViewCell, but
   LtHomeCustomCell *cell = (LtHomeCustomCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
  if (cell == nil) {
    cell = [[LtHomeCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
  }

cell.image.image = [UIImage imageNamed:[mPics objectAtIndex:indexPath.row]];

NSString *magName = [[mFiles objectAtIndex:indexPath.row]stringByReplacingOccurrencesOfString:@"../Lumina.app/" withString:@""];
magName = [magName stringByReplacingOccurrencesOfString:@"lumina" withString:@""];
magName = [magName stringByReplacingOccurrencesOfString:@".pdf" withString:@""];
magName = [[@"Triathlon LUMINA " stringByAppendingString:magName]stringByAppendingString:@""];

cell.descriptionLabel.text = magName;

return cell;
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor colorWithRed:(116/255.0) green:(167/255.0) blue:(179/255.0) alpha:1.0];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 110;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}

@end

Maintenant, je ne sais pas si cette ligne vous aidera, mais comme j'ai besoin de plus de choses, j'ai pris l'approche de faire la table manuellement.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    cell.backgroundColor = [UIColor colorWithRed:(116/255.0) green:(167/255.0) blue:(179/255.0) alpha:1.0];
}

David

0 votes

Vous n'avez probablement pas besoin de la méthode déléguée willDisplayCell. Vous pourriez obtenir la même chose en déplaçant le code de cette méthode dans cellForRowAtIndexPath. Mais ma question portait sur les cellules statiques. Je voudrais éviter d'utiliser des prototypes dynamiques/cellules générées dans le code.

0 votes

Oui, vous avez raison, j'ai compris juste après avoir posté cette réponse. Pour ce qui est de votre problème, cela ne fonctionnerait-il pas si vous utilisiez la fonction cellForRowAtIndexPath et si vous filtriez simplement la cellule statique en utilisant la ligne indexPath.row ? Vous pouvez alors simplement faire un cycle if ou un switch et changer la couleur de fond des cellules individuelles.

0 votes

Je ne pense pas que vous puissiez utiliser une source de données lorsque vous utilisez des cellules statiques :) Les cellules statiques sont destinées à être construites dans IB avec le principe "What you see is what you get" à l'esprit. Il est très pratique de les utiliser lorsque votre écran a un nombre fixe d'options. Ensuite, vous pouvez facilement assigner des segments à ces cellules statiques, ou même y placer des vues conteneurs séparant votre écran en modules, où chaque module est contrôlé par un contrôleur de vue enfant distinct. Cela améliore considérablement la réutilisabilité de votre code.

1voto

middleseatman Points 98

Il existe un moyen beaucoup plus simple de remplacer la couleur d'arrière-plan des cellules. Sous-classez UITableViewCell et définissez-la comme la classe de la cellule statique du tableau. Puis modifiez-la :

-(void) willMoveToSuperview:(UIView *)newSuperview  {
    self.backgroundColor = [UIColor ...];
}

où [UIColor ...] = la couleur que vous voulez (par exemple [UIColor clearColor] etc.) ;

0 votes

Je préfère cette méthode si je suis déjà en train de sous-classer - cela permet de garder les préoccupations avec la cellule. C'est quand même un bug, on ne devrait pas avoir besoin de ce code !

1voto

Thiago Pereira Points 21

Changez plutôt la couleur d'arrière-plan du ContentView et cela fonctionnera.

0 votes

Notez toutefois que la vue du contenu n'inclut pas la zone située sous la vue des accessoires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X