QuartzCore .layer.shadow aspire les performances. Ils semblent avoir besoin d'être redéfinis chaque fois que quelque chose change, ce qui fait que tout est en retard.
Dégradé Coregraphics (pour les ombres 1 way) – ne semble pas correct. Si votre dégradé passe de 0,3 alpha à 0, il a un effet étrange où vous pouvez le 'voir' s'arrêter. Ça n'a pas l'air sympa ou naturel. Peut-être que ce n'est pas tergiversé, mais je suis sûr que j'ai entendu les dégradés charts de base sont. C'est étrange, je ne sais pas.
Ombre Coregraphics – prenez un peu de time pour les rendre tels que vous les avez définis, mais sinon de grandes performances. C'est juste à ce moment-là que vous attendez qu'une vue apparaisse, car elle doit d'abord rendre son ombre, c'est le problème.
Je dois donc manquer quelque chose. Existe-t-il une autre méthode qui semble correcte, et qui soit rapide à la fois en termes de time et de performance?
L'ajout d'un shadowPath devrait vous donner un énorme coup de pouce. L'exemple suivant suppose que vous ne voulez que l'ombre sur les côtés de votre vue
CGPathRef path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath; [view.layer setShadowPath:path];
EDIT: Par défaut, un CALayer dessine une ombre pendant les animations, le code suivant vous permet de mettre en cache l'ombre en tant que bitmap et de le réutiliser au lieu de le redessiner:
self.view.layer.shouldRasterize = YES; // Don't forget the rasterization scale // I spent days trying to figure out why retina display assets weren't working as expected self.view.layer.rasterizationScale = [UIScreen mainScreen].scale;
J'ai souvent vu des gens utiliser le calque de la vue d'impact des performances ÉNORMES pour créer un angle arrondi ou un ombres à paupières. Quelque chose comme ça:
[v.layer setCornerRadius:30.0f]; [v.layer setBorderColor:[UIColor lightGrayColor].CGColor]; [v.layer setBorderWidth:1.5f]; [v.layer setShadowColor:[UIColor blackColor].CGColor]; [v.layer setShadowOpacity:0.8]; [v.layer setShadowRadius:3.0]; [v.layer setShadowOffset:CGSizeMake(2.0, 2.0)]; .....
Cela a un énorme impact sur les performances, en particulier avec l'ombre. Mettre des vues comme ceci dans un UITableView (ou n'importe quoi qui bouge) créera une expérience de défilement android-ish, vous ne voulez pas cela. Si vous avez besoin d'animer ou de déplacer la vue, évitez de créer des coins arrondis ou de faire tomber des ombres comme ça par tous les moyens!
Rencontrez Core Graphics
J'ai créé une sous-class UIView simple pour vous montrer comment get le même résultat d'une manière légèrement différente. Il utilise Core Graphics pour dessiner la vue et contrairement au code ci-dessus, il n'a pas d'impact sur les performances.
Voici le code du dessin:
- (void)drawRect:(CGRect)rect { CGContextRef ref = UIGraphicsGetCurrentContext(); /* We can only draw inside our view, so we need to inset the actual 'rounded content' */ CGRect contentRect = CGRectInset(rect, _shadowRadius, _shadowRadius); /* Create the rounded path and fill it */ UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:contentRect cornerRadius:_cornerRadius]; CGContextSetFillColorWithColor(ref, _fillColor.CGColor); CGContextSetShadowWithColor(ref, CGSizeMake(0.0, 0.0), _shadowRadius, _shadowColor.CGColor); [roundedPath fill]; /* Draw a subtle white line at the top of the view */ [roundedPath addClip]; CGContextSetStrokeColorWithColor(ref, [UIColor colorWithWhite:1.0 alpha:0.6].CGColor); CGContextSetBlendMode(ref, kCGBlendModeOverlay); CGContextMoveToPoint(ref, CGRectGetMinX(contentRect), CGRectGetMinY(contentRect)+0.5); CGContextAddLineToPoint(ref, CGRectGetMaxX(contentRect), CGRectGetMinY(contentRect)+0.5); CGContextStrokePath(ref); }
Voir ce blog: http://damir.me/rounded-uiview-with-shadow-the-rightway