UIImage as CAShapeLayer contents

2020-03-26 03:48发布

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 = [CAShapeLayer layer];
leftDot.opacity = 1.0;
leftDot.frame = CGRectMake(leftRef.CGPointValue.x, leftRef.CGPointValue.y, 2 * radius, 2 * radius);
leftDot.position = CGPointMake(leftRef.CGPointValue.x + 4, leftRef.CGPointValue.y + 4);
leftDot.cornerRadius = radius;
[leftDot setContents:[UIImage imageNamed: @"glow.png"]];

[self.layer addSublayer: leftDot];

5条回答
啃猪蹄的小仙女
2楼-- · 2020-03-26 04:04

You have to set the CGImage for the layer

leftDot.fillColor=[UIColor clearColor].CGColor ;
[leftDot setContents:(__bridge id)[UIImage imageNamed: @"glow.png"].CGImage];
查看更多
家丑人穷心不美
3楼-- · 2020-03-26 04:06

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.

查看更多
男人必须洒脱
4楼-- · 2020-03-26 04:18

You can get the image to appear by setting the fillColor rather than the contents:

layer.fillColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"image"]].CGColor;
查看更多
来,给爷笑一个
5楼-- · 2020-03-26 04:26

[NOTE: updated to Swift 2.2 and Swift 3]

Quick answer: use CALayer

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

Longer answer: keep using CAShapeLayer

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.

查看更多
倾城 Initia
6楼-- · 2020-03-26 04:29
layerName.contents = (id)[[UIImage imageNamed:@"img.PNG"] CGImage];
查看更多
登录 后发表回答