352 votes

Comment puis-je dessiner une ombre sous un UIView?

Je suis en train de dessiner une ombre sous le bord inférieur de la UIView en Cocoa Touch. Je comprends que je devrais utiliser CGContextSetShadow() pour dessiner l'ombre, mais le Quartz 2D guide de programmation est un peu vague:

  1. Enregistrer l'état graphique.
  2. Appeler la fonction CGContextSetShadow, passant les valeurs appropriées.
  3. Effectuer tous les dessins à laquelle vous souhaitez appliquer des ombres.
  4. Restaurer l'état graphique

J'ai essayé ce qui suit, en UIView sous-classe:

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    CGContextRestoreGState(currentContext);
    [super drawRect: rect];
}

..mais cela ne fonctionne pas pour moi et je suis un peu coincé sur une (des) où aller et (b) s'il y a quelque chose que je doit faire pour que mes UIView pour faire ce travail?

789voto

ollie Points 3681

Une approche de loin plus simple consiste à définir certains attributs de couche de la vue à l'initialisation:

 self.layer.masksToBounds = NO;
self.layer.cornerRadius = 8; // if you like rounded corners
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;
 

232voto

ZuYuan Points 2114
 self.layer.masksToBounds = NO;
self.layer.cornerRadius = 8; // if you like rounded corners
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;
 

Cela ralentira l'application. L'ajout de la ligne suivante peut améliorer les performances tant que votre vue est visiblement rectangulaire:

 self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
 

160voto

Antzi Points 1251

Même solution, mais juste pour vous rappeler: vous pouvez définir l'ombre directement dans le storyboard. Ex: entrez la description de l'image ici

98voto

Christian Brunschen Points 928

Dans votre code, vous économiser de l' GState de le contexte actuel, le configurer pour dessiner une ombre .. et de le restaurer à ce qu'il était avant que vous avez configuré pour dessiner une ombre. Puis, enfin, l'appel de la super-classe de mise en œuvre de l' drawRect: .

Un dessin qui devrait être affectée par le paramètre ombre qui doit arriver après

CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);

mais avant

CGContextRestoreGState(currentContext);

Donc, si vous voulez la superclasse, drawRect: à être "enveloppé" dans l'ombre, alors que diriez-vous si vous réorganisez votre code comme celui-ci?

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    [super drawRect: rect];
    CGContextRestoreGState(currentContext);
}

13voto

Srikar Appal Points 26892

Je l'utilise dans le cadre de mes utils. Avec cela, nous pouvons non seulement définir l'ombre, mais aussi obtenir un angle arrondi pour tout UIView . Vous pouvez également définir quelle ombre de couleur vous préférez. Normalement, le noir est préférable, mais parfois, lorsque l'arrière-plan n'est pas blanc, vous pouvez vouloir autre chose. Voici ce que j'utilise -

 in utils.m
+ (void)roundedLayer:(CALayer *)viewLayer 
              radius:(float)r 
              shadow:(BOOL)s
{
    [viewLayer setMasksToBounds:YES];
    [viewLayer setCornerRadius:r];        
    [viewLayer setBorderColor:[RGB(180, 180, 180) CGColor]];
    [viewLayer setBorderWidth:1.0f];
    if(s)
    {
        [viewLayer setShadowColor:[RGB(0, 0, 0) CGColor]];
        [viewLayer setShadowOffset:CGSizeMake(0, 0)];
        [viewLayer setShadowOpacity:1];
        [viewLayer setShadowRadius:2.0];
    }
    return;
}
 

Pour l'utiliser, nous devons appeler ceci - [utils roundedLayer:yourview.layer radius:5.0f shadow:YES];

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