J'essaie d'ajouter une ombre portée aux vues superposées, les vues s'effondrent permettant au contenu d'autres vues d'être vu, dans cette veine, je veux rester view.clipsToBounds
activé afin que lorsque les vues se réduisent, leur contenu soit tronqué.
Cela semble avoir rendu difficile pour moi d'ajouter une ombre portée aux calques, car lorsque clipsToBounds
j'active les ombres sont également coupées.
J'ai essayé de manipuler view.frame
et view.bounds
d'ajouter une ombre portée au cadre mais de permettre aux limites d'être suffisamment grandes pour l'englober, mais je n'ai pas eu de chance avec cela.
Voici le code que j'utilise pour ajouter une ombre (cela ne fonctionne qu'avec clipsToBounds
OFF comme indiqué)
view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
Voici une capture d'écran de l'ombre appliquée au calque gris le plus clair du haut. J'espère que cela donne une idée de la façon dont mon contenu se chevauchera si clipsToBounds
est désactivé.
Comment puis-je ajouter une ombre à mon UIView
et conserver mon contenu découpé?
Edit: Je voulais juste ajouter que j'ai également joué avec l'utilisation d'images d'arrière-plan avec des ombres, ce qui fonctionne bien, mais j'aimerais toujours connaître la meilleure solution codée pour cela.
masksToBounds = NO;
j'ai essayé d'ajouter à mon original - avec les deux tentatives que j'ai gardéesclipsToBounds = YES;
activées - les deux n'ont pas réussi à couper le contenu. voici une capture d'écran de ce qui s'est passé avec votre exemple> youtu.be/tdpemc_XdpsUIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:5.0];
. Non testé mais devrait donner le résultat souhaité.layoutSubviews()
est appelée. Et si nous ne compensons pas à cet endroit en ajustant leshadowPath
pour refléter la taille actuelle, nous aurions une vue redimensionnée mais l'ombre serait toujours l'ancienne taille (initiale) et ne s'afficherait pas ou ne verrait pas où elle ne devrait pas .Réponse de Wasabii dans Swift 2.3:
Et dans Swift 3/4/5:
Mettez ce code dans layoutSubviews () si vous utilisez AutoLayout.
Dans SwiftUI, c'est beaucoup plus simple:
la source
layoutSubviews
CGSize(width: 0, height: 0.5)
view.bounds
n'a pas été créé de manière si évidente que jeshadowPath
ne peux pas faire référence au rect de la vue, mais à certains à laCGRectZero
place. Quoi qu'il en soit, mettre cela souslayoutSubviews
résolu mon problème enfin!L'astuce consiste à définir
masksToBounds
correctement la propriété du calque de votre vue:et cela devrait fonctionner.
( Source )
la source
Vous pouvez créer une extension pour UIView pour accéder à ces valeurs dans l'éditeur de conception
la source
Vous pouvez également définir une ombre sur votre vue à partir du storyboard
la source
Sur la vueWillLayoutSubviews:
Utilisation de l'extension d'UIView:
Usage:
la source
targetView: UIView
et de supprimer la frange.self
? Cela me semble beaucoup plus pratique.if let
syntaxe au lieu de!
Donc oui, vous devriez préférer la propriété shadowPath pour les performances, mais aussi: Depuis le fichier d'en-tête de CALayer.shadowPath
Spécifier explicitement le chemin à l'aide de cette propriété améliorera généralement * les performances de rendu, tout comme le partage du même chemin * référence sur plusieurs couches
Une astuce moins connue consiste à partager la même référence sur plusieurs couches. Bien sûr, ils doivent utiliser la même forme, mais c'est courant avec les cellules de vue tableau / collection.
Je ne sais pas pourquoi cela devient plus rapide si vous partagez des instances, je suppose que cela met en cache le rendu de l'ombre et peut le réutiliser pour d'autres instances de la vue. Je me demande si c'est encore plus rapide avec
la source