J'ai un UIBezierPath
à l'intérieur de ma fonction UIView draw(_ rect: CGRect)
personnalisée. Je voudrais remplir le chemin avec une couleur dégradée. S'il vous plaît, quelqu'un peut-il me guider comment puis-je faire cela.
Je dois remplir le clip avec une couleur dégradée, puis tracer le chemin avec une couleur noire.
Il y a quelques articles dans SO qui ne résout pas le problème. Par exemple Swift: Dégradé le long d'un chemin plus bizarre (en utilisant CALayers) cet article explique comment dessiner sur un calque dans UIView
mais pas dans un UIBezierPath
.
NB: je travaille sur Swift-3
Pour répondre à votre question,
J'ai un UIBezierPath dans ma fonction de dessin UIView personnalisé (_ rect: CGRect). Je voudrais remplir le chemin avec une couleur dégradée.
Disons que vous avez un chemin ovale,
let path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100))
Pour créer un dégradé,
let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.colors = [UIColor.Magenta.cgColor, UIColor.cyan.cgColor]
Nous avons besoin d'une couche de masque pour le gradient,
let shapeMask = CAShapeLayer()
shapeMask.path = path.cgPath
Maintenant, définissez ce shapeLayer
comme mask
du gradient
calque et ajoutez-le au view
calque comme subLayer
gradient.mask = shapeMask
yourCustomView.layer.addSublayer(gradient)
Mettre à jour Créez une couche de base avec un trait et ajoutez-la avant de créer une couche de dégradé.
let shape = CAShapeLayer()
shape.path = path.cgPath
shape.lineWidth = 2.0
shape.strokeColor = UIColor.black.cgColor
self.view.layer.addSublayer(shape)
let gradient = CAGradientLayer()
gradient.frame = path.bounds
gradient.colors = [UIColor.Magenta.cgColor, UIColor.cyan.cgColor]
let shapeMask = CAShapeLayer()
shapeMask.path = path.cgPath
gradient.mask = shapeMask
self.view.layer.addSublayer(gradient)
Vous pouvez le faire directement dans Core Graphics sans utiliser les classes CALayer
. Utilisez bezierPath.addClip()
pour définir le chemin du Bézier comme région de découpage. Toutes les commandes de dessin suivantes seront masquées dans cette région.
J'utilise cette fonction wrapper dans l'un de mes projets:
func drawLinearGradient(inside path:UIBezierPath, start:CGPoint, end:CGPoint, colors:[UIColor])
{
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
defer { ctx.restoreGState() } // clean up graphics state changes when the method returns
path.addClip() // use the path as the clipping region
let cgColors = colors.map({ $0.cgColor })
guard let gradient = CGGradient(colorsSpace: nil, colors: cgColors as CFArray, locations: nil)
else { return }
ctx.drawLinearGradient(gradient, start: start, end: end, options: [])
}