J'essaie d'append une ombre scope aux vues qui sont superposées les unes sur les autres, les vues se view.clipsToBounds
ce qui permet de voir le contenu des autres vues. Dans ce sens, je veux conserver view.clipsToBounds
pour que les vues view.clipsToBounds
leur contenu est coupé.
Cela semble avoir rendu difficile pour moi d'append une ombre scope aux calques comme quand je tourne des clipsToBounds
les ombres sont également coupés.
J'ai essayé de manipuler view.frame
et view.bounds
afin d'append une ombre scope au cadre mais permettre aux limites d'être assez grandes pour l'englober, mais je n'ai pas eu de chance avec ça.
Voici le code que j'utilise pour append 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 à la couche grise la plus claire. 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 append une ombre à mon UIView
et conserver mon contenu?
Edit: Je voulais juste append que j'ai aussi joué avec l'utilisation d'images de fond avec des ombres, ce qui fonctionne bien, mais j'aimerais quand même connaître la meilleure solution codée pour cela.
Essaye ça:
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds]; view.layer.masksToBounds = NO; view.layer.shadowColor = [UIColor blackColor].CGColor; view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f); view.layer.shadowOpacity = 0.5f; view.layer.shadowPath = shadowPath.CGPath;
Tout d'abord : L' UIBezierPath
utilisé comme shadowPath
est crucial. Si vous ne l'utilisez pas, vous ne remarquerez peut-être pas une différence au début, mais l'œil vif observera un certain retard lors d'events tels que la rotation de l'appareil et / ou similaire. C'est un tweak de performance important.
En ce qui concerne votre problème en particulier : La ligne importante est view.layer.masksToBounds = NO
. Il désactive le découpage des sous-couches de la couche de la vue qui s'étendent plus loin que les limites de la vue.
Pour ceux qui se requestnt quelle est la différence entre masksToBounds
(sur le calque) et la propriété clipToBounds
la vue: Il n'y en a pas vraiment. Toggle un aura un effet sur l'autre. Juste un niveau différent d'abstraction.
Swift 2.2:
override func layoutSubviews() { super.layoutSubviews() let shadowPath = UIBezierPath(rect: bounds) layer.masksToBounds = false layer.shadowColor = UIColor.blackColor().CGColor layer.shadowOffset = CGSizeMake(0.0, 5.0) layer.shadowOpacity = 0.5 layer.shadowPath = shadowPath.CGPath }
Swift 3:
override func layoutSubviews() { super.layoutSubviews() let shadowPath = UIBezierPath(rect: bounds) layer.masksToBounds = false layer.shadowColor = UIColor.black.cgColor layer.shadowOffset = CGSize(width: 0.0, height: 5.0) layer.shadowOpacity = 0.5 layer.shadowPath = shadowPath.cgPath }
La réponse de Wasabii dans Swift 2.3:
let shadowPath = UIBezierPath(rect: view.bounds) view.layer.masksToBounds = false view.layer.shadowColor = UIColor.blackColor().CGColor view.layer.shadowOffset = CGSize(width: 0, height: 0.5) view.layer.shadowOpacity = 0.2 view.layer.shadowPath = shadowPath.CGPath
Et dans Swift 3/4:
let shadowPath = UIBezierPath(rect: view.bounds) view.layer.masksToBounds = false view.layer.shadowColor = UIColor.black.cgColor view.layer.shadowOffset = CGSize(width: 0, height: 0.5) view.layer.shadowOpacity = 0.2 view.layer.shadowPath = shadowPath.cgPath
Placez ce code dans layoutSubviews () si vous utilisez AutoLayout.
L'astuce consiste à définir masksToBounds
propriété masksToBounds
du masksToBounds
de votre vue:
view.layer.masksToBounds = NO;
et ça devrait marcher.
( Source )
Sur viewWillLayoutSubviews:
override func viewWillLayoutSubviews() { sampleView.layer.masksToBounds = false sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor; sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0) sampleView.layer.shadowOpacity = 1.0 }
En utilisant l'extension de UIView:
extension UIView { func addDropShadowToView(targetView:UIView? ){ targetView!.layer.masksToBounds = false targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor; targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0) targetView!.layer.shadowOpacity = 1.0 } }
Usage:
sampleView.addDropShadowToView(sampleView)
Vous pouvez créer une extension pour UIView pour accéder à ces valeurs dans l'éditeur de design
extension UIView{ @IBInspectable var shadowOffset: CGSize{ get{ return self.layer.shadowOffset } set{ self.layer.shadowOffset = newValue } } @IBInspectable var shadowColor: UIColor{ get{ return UIColor(cgColor: self.layer.shadowColor!) } set{ self.layer.shadowColor = newValue.cgColor } } @IBInspectable var shadowRadius: CGFloat{ get{ return self.layer.shadowRadius } set{ self.layer.shadowRadius = newValue } } @IBInspectable var shadowOpacity: Float{ get{ return self.layer.shadowOpacity } set{ self.layer.shadowOpacity = newValue } } }