J'ai implémenté avec succès le dessin d'une ombre autour de ma UIView
comme ceci:
block1.layer.masksToBounds = NO;
block1.layer.shadowOffset = CGSizeMake(0, 0);
block1.layer.shadowRadius = 1;
block1.layer.shadowOpacity = 0.7;
Ce qui se passe maintenant, c’est que j’ai une UIView
rectangulaire et je voudrais tracer l’ombre autour de celle-ci sur trois côtés, en laissant le côté bas sans l’ombre.
Je sais que je dois spécifier le block1.layer.shadowPath
en créant une nouvelle UIBezierPath
mais je ne sais pas comment le faire.
De toute évidence, régler layer.shadowOffset
ne me convient pas.
Merci d'avance!
Je sais que vous dites que le réglage de layer.shadowOffset
ne fonctionnera pas pour vous, mais que vous êtes autorisé à entrer des valeurs négatives. Le réglage de layer.shadowOffset = CGSizeMake(0.0, -2.0)
se rapprocherait donc de l’effet recherché, mais bien sûr, je pense que vous voulez que ce soit le même trois côtés.
Alors on y va avec layer.shadowPath
!
UIView *block1 = [[UIView alloc] initWithFrame:CGRectMake(32.0, 32.0, 128.0, 128.0)];
[block1 setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:block1];
block1.layer.masksToBounds = NO;
block1.layer.shadowOffset = CGSizeMake(0, 0);
block1.layer.shadowRadius = 1;
block1.layer.shadowOpacity = 0.7;
UIBezierPath *path = [UIBezierPath bezierPath];
// Start at the Top Left Corner
[path moveToPoint:CGPointMake(0.0, 0.0)];
// Move to the Top Right Corner
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame), 0.0)];
// Move to the Bottom Right Corner
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame), CGRectGetHeight(block1.frame))];
// This is the extra point in the middle :) Its the secret sauce.
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame) / 2.0, CGRectGetHeight(block1.frame) / 2.0)];
// Move to the Bottom Left Corner
[path addLineToPoint:CGPointMake(0.0, CGRectGetHeight(block1.frame))];
// Move to the Close the Path
[path closePath];
block1.layer.shadowPath = path.CGPath;
Et pour vous donner une idée de ce qui se passe, voici le chemin de l'ombre que vous venez de dessiner :)
Il est possible de simplement déplacer ce point médian supplémentaire avant ou après les autres lignes pour choisir le côté qui sera omis.
Un peu d'amélioration pour d'autres réponses, merci à Ashok R pour le code Swift.
Comme nous étions en train de créer une vue triangulaire à l'arrière-plan de la vue avec des ombres sur tous les côtés, un triangle blanc sur les côtés ne nécessite pas d'ombre.
Il casse en cas de vues avec une largeur comparativement plus grande que la hauteur.
Une solution de contournement consistera à déplacer le chemin de la ligne où l'ombre n'est pas nécessaire un peu vers ce côté de la vue, au lieu de créer la vue triangulaire Chemin complètement .
J'ai créé une extension pour ça -
extension UIView {
func addshadow(top: Bool,
left: Bool,
bottom: Bool,
right: Bool,
shadowRadius: CGFloat = 2.0) {
self.layer.masksToBounds = false
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
self.layer.shadowRadius = shadowRadius
self.layer.shadowOpacity = 1.0
let path = UIBezierPath()
var x: CGFloat = 0
var y: CGFloat = 0
var viewWidth = self.frame.width
var viewHeight = self.frame.height
// here x, y, viewWidth, and viewHeight can be changed in
// order to play around with the shadow paths.
if (!top) {
y+=(shadowRadius+1)
}
if (!bottom) {
viewHeight-=(shadowRadius+1)
}
if (!left) {
x+=(shadowRadius+1)
}
if (!right) {
viewWidth-=(shadowRadius+1)
}
// selecting top most point
path.move(to: CGPoint(x: x, y: y))
// Move to the Bottom Left Corner, this will cover left edges
/*
|☐
*/
path.addLine(to: CGPoint(x: x, y: viewHeight))
// Move to the Bottom Right Corner, this will cover bottom Edge
/*
☐
-
*/
path.addLine(to: CGPoint(x: viewWidth, y: viewHeight))
// Move to the Top Right Corner, this will cover right Edge
/*
☐|
*/
path.addLine(to: CGPoint(x: viewWidth, y: y))
// Move back to the initial point, this will cover the top Edge
/*
_
☐
*/
path.close()
self.layer.shadowPath = path.cgPath
}
et réglez la valeur booléenne sur le côté où vous souhaitez que l'ombre apparaisse
myView.addshadow(top: false, left: true, bottom: true, right: true, shadowRadius: 2.0)
// le rayon de l'ombre est facultatif ci-dessus et est défini par défaut à 2.0
ou myView.addshadow(top: true, left: true, bottom: true, right: true, shadowRadius: 2.0)
ou myView.addshadow(top: false, left: false, bottom: true, right: true, shadowRadius: 2.0)
Mise à jourRyan PoolosRéponse à Swift 3.0
Merci àRyan Poolos
class sampleViewController: UIViewController {
var block1: UIView! = nil
override func viewDidLoad() {
super.viewDidLoad()
block1 = UIView(frame: CGRect(x: 32.0, y: 32.0, width: 128.0, height: 128.0))
block1.backgroundColor = UIColor.orange
self.view.addSubview(block1)
block1.layer.masksToBounds = false
block1.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
block1.layer.shadowRadius = 1.0
block1.layer.shadowOpacity = 0.7
let path = UIBezierPath()
// Start at the Top Left Corner
path.move(to: CGPoint(x: 0.0, y: 0.0))
// Move to the Top Right Corner
path.addLine(to: CGPoint(x: block1.frame.size.width, y: 0.0))
// Move to the Bottom Right Corner
path.addLine(to: CGPoint(x: block1.frame.size.width, y: block1.frame.size.height))
// This is the extra point in the middle :) Its the secret sauce.
path.addLine(to: CGPoint(x: block1.frame.size.width/2.0, y: block1.frame.size.height/2.0))
// Move to the Bottom Left Corner
path.addLine(to: CGPoint(x: 0.0, y: block1.frame.size.height))
path.close()
block1.layer.shadowPath = path.cgPath
}
}
Résultat:
Essaye ça
extension CALayer {
func applySketchShadow(color: UIColor, alpha: CGFloat, x: CGFloat, y: CGFloat, blur: CGFloat, spread: CGFloat)
{
shadowColor = color.cgColor
shadowOpacity = alpha
shadowOffset = CGSize(width: x, height: y)
shadowRadius = blur / 2.0
if spread == 0 {
shadowPath = nil
} else {
let dx = -spread
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(rect: rect).cgPath
}
}