2010-07-18 3 views
7

Je voudrais créer un fond dégradé UITableViewCell comme l'application par défaut de l'horloge qui vient sur l'iPhone. Je ne suis pas sûr exactement comment accomplir cela. Est-ce que je crée une image et la règle:Comment définir un arrière-plan dégradé UITableViewCell?

cell.contentView.backgroundColor = [UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"background.png"]]; 

ou y at-il une autre/meilleure approche?

+0

Je pense que c'est le seul moyen – tadejsv

+1

Et si ma taille n'est pas de taille égale?Comment créer mon graphique d'arrière-plan? –

Répondre

13

Je trouve la réponse existante à cette question, mais n'a pas été satisfaite. Voici une approche alternative qui nécessite moins de code, ne nécessite pas de redéfinir les méthodes et peut être appliquée à n'importe quelle vue. L'idée est d'ajouter un CAGradientLayer en tant que sous-couche au calque UIView. Je ne pouvais pas trouver cette approche documentée nulle part donc je voulais partager.

Ajouter un CAGradientLayer à tout UIView comme suit:

Catégorie sur UIView tête - UIView + Gradient.h:

#import <UIKit/UIKit.h> 

@interface UIView (Gradient) 
-(void) addLinearUniformGradient:(NSArray *)stopColors; 
@end 

Catégorie sur UIView mise en œuvre UIView + Gradient.m:

#import "UIView+Gradient.h" 
#import <QuartzCore/QuartzCore.h> 

@implementation UIView (Gradient) 

-(void) addLinearUniformGradient:(NSArray *)stopColors 
{ 
    CAGradientLayer *gradient = [CAGradientLayer layer]; 
    gradient.frame = self.bounds; 
    gradient.colors = stopColors; 
    gradient.startPoint = CGPointMake(0.5f, 0.0f); 
    gradient.endPoint = CGPointMake(0.5f, 1.0f);  
    [self.layer addSublayer:gradient]; 
} 

@end 

Comment définir le dégradé sur le fond de UITableViewCell tion de la UITableViewCell:

// Set the gradient for the cell's background 
CGRect backgroundViewFrame = cell.contentView.frame; 
backgroundViewFrame.size.height = yourCellHeight; 
cell.backgroundView = [[UIView alloc] initWithFrame:backgroundViewFrame]; 
[cell.backgroundView addLinearUniformGradient:[NSArray arrayWithObjects: 
               (id)[[UIColor redColor] CGColor], 
               (id)[[UIColor greenColor] CGColor], nil]]; 

Cet exemple ne montre comment configurer un simple gradient à deux arrêts (avec un espacement uniforme). Un rapide coup d'oeil à la documentation CAGradientLayer vous montrera comment configurer des dégradés plus complexes.

(* EDIT POUR PLUS D'INFORMATIONS SUPPLÉMENTAIRES IMPORTANTS *)

Une chose supplémentaire à garder à l'esprit est que si vous ajoutez la couche de gradient dans une méthode comme tableView: cellForRowAtIndexPath, les UITableViewCells sont en être général réutilisé (ie [tableView dequeueReusableCellWithIdentifier: @ "foo"]). Étant donné que les cellules sont réutilisées, si vous ajoutez toujours une couche de dégradé à une cellule de vue de table chaque fois que la cellule est supprimée, vous pouvez ajouter plusieurs couches de dégradé à la cellule tableview pendant la durée de vie de la cellule. Cela peut être une source de performance réduite. Ce problème peut se produire sans aucun changement dans les résultats visibles, il peut donc être difficile à détecter/observer. Il y a plusieurs façons de résoudre ceci mais une chose que vous pouvez faire est de modifier le code original ci-dessus en plus d'ajouter CAGradientLayer, pour retourner le CAGradientLayer créé à l'appelant. Ensuite, il est assez simple d'écrire une autre méthode de catégorie qui permet à la couche de gradient à enlever si elle est effectivement contenu dans la vue:

-(BOOL) removeGradient:(CAGradientLayer *)gradientLayer 
{ 
    // Search for gradient layer and remove it 
    NSArray *layers = [self.layer sublayers]; 
    for (id layer in layers) { 
     if (layer == gradientLayer) { 
      [gradientLayer removeFromSuperlayer]; 
      return YES; 
     } 
    } 

    // Failed to find the gradient layer in this view 
    return NO; 
} 

Retrait du gradient n'est pas nécessaire pour tous les cas d'utilisation, mais si votre cas d'utilisation entraîne la réutilisation des cellules, vous pouvez envisager de supprimer le dégradé. Un point à considérer pour appeler cette méthode provient de la méthode prepareForReuse de UITableViewCell. Je m'excuse que ma solution originale n'a pas résolu ce problème. Mais puisque c'est quelque chose qui peut être assez subtile, je voulais mettre à jour ma réponse avec cette information supplémentaire.

+0

J'ai essayé de l'appliquer à une cellule groupée mais le remplissage dégradé est une boîte sans coin arrondi. Ai-je manqué quelque chose? – Claus

+0

Hmm, vous devrez peut-être définir le rayon/masque du calque. Lisez les documents sur les deux méthodes suivantes: [self.layer setCornerRadius: 10.0]; [self.layer setMasksToBounds: YES]; Espérons que cela vous pointe dans la bonne direction. – Chris

Questions connexes