If I create a CAShapeLayer with just a background color it shows up, but if i set the content to an image, nothing shows.
CAShapeLayer* leftDot = [CAShapeLa
You can get the image to appear by setting the fillColor
rather than the contents
:
layer.fillColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"image"]].CGColor;
CAShapeLayer doesn't work that way. You would create a normal CALayer with the image as its content and then use the shape layer as the mask of that layer to achieve the effect you are after.
layerName.contents = (id)[[UIImage imageNamed:@"img.PNG"] CGImage];
You have to set the CGImage for the layer
leftDot.fillColor=[UIColor clearColor].CGColor ;
[leftDot setContents:(__bridge id)[UIImage imageNamed: @"glow.png"].CGImage];
[NOTE: updated to Swift 2.2 and Swift 3]
As explained in CAShapeLayer Class Reference, a CAShapeLayer
is used for drawing shapes using a custom path. Setting an image as its contents
will simply be ignored.
If you just want to show an image in a layer (let's suppose your file is named image.png
), you can use a CALayer
and set its contents
property so that it references the CGImage
representation of your image:
Swift 2.2:
let layer = CALayer()
layer.contents = UIImage(named: "image")?.CGImage
Swift 3:
let layer = CALayer()
layer.contents = UIImage(named: "image")?.cgImage
Since the OP asked specifically about CAShapeLayer
, the question may read like "How can I crop an image into a specific shape using CAShapeLayer
?"
There are two solutions I'd suggest you try:
1) Masking
Create a normal CALayer
and set the image as its contents
. Then create a CAShapeLayer
with the path you like and use it as the first layer's mask
.
Swift 2.2:
let imageLayer = CALayer()
imageLayer.contents = UIImage(named: "image")?.CGImage // Assign your image
imageLayer.frame = ... // Define a frame
let maskPath = UIBezierPath(...) // Create your path
let maskLayer = CAShapeLayer()
maskLayer.path = maskPath.CGPath
imageLayer.mask = maskLayer // Set the mask
Swift 3:
let imageLayer = CALayer()
imageLayer.contents = UIImage(named: "image")?.cgImage // Assign your image
imageLayer.frame = ... // Define a frame
let maskPath = UIBezierPath(...) // Create your path
let maskLayer = CAShapeLayer()
maskLayer.path = maskPath.cgPath
imageLayer.mask = maskLayer // Set the mask
Don't forget to set the right frames and paths, and you should be able to achieve the effect you wanted.
2) Fill color
Create a CAShapeLayer
with the path you like, then use your image as its fillColor
.
Swift 2.2:
let path = UIBezierPath(...) // Create your path
let layer = CAShapeLayer()
layer.path = path.CGPath
let image = UIImage(named: "image") // Assign your image
layer.fillColor = UIColor(patternImage: image!).CGColor
Swift 3:
let path = UIBezierPath(...) // Create your path
let layer = CAShapeLayer()
layer.path = path.cgPath
let image = UIImage(named: "image") // Assign your image
layer.fillColor = UIColor(patternImage: image!).cgColor
You may find this approach easier at first, but controlling the way the image fills your shape is not trivial at all.