简体   繁体   中英

Adding an image to a CAShapeLayer

I'm attempting to render a static image inside a CAShapeLayer that is nested within a UIView 's layer. All of the adornments of the shape (ie borders, colors, paths, etc.) render properly in the view.

However , the supplied CGImage for the CALayer.contents property does not render in the view at any point (as far as I can tell). I've been trying to figure this behavior out for a while and am stumped with the documentation from Apple:

If you are using the layer to display a static image , you can set this property to the CGImage containing the image you want to display.... Assigning a value to this property causes the layer to use your image rather than create a separate backing store.

If the layer object is tied to a view object, you should avoid setting the contents of this property directly . The interplay between views and layers usually results in the view replacing the contents of this property during a subsequent update .

That's great to know! It's probably exactly what's happening in this scenario: the UIView is updating and replacing its contents. Except the provided workaround isn't very clear and I haven't been able to find examples that solve this problem.

Anyone have any suggestions on how to set a static image 'indirectly' on a CAShapeLayer and avoid having it removed by the superview (almost immediately)?

At first I thought you couldn't install an image into the contents of a CAShapeLayer and have it work, but I was wrong. It does work. Consider this code:

class ImageWithShapeView: UIView {

    let shapeLayer = CAShapeLayer()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        layer.borderWidth = 1.0
        shapeLayer.frame = self.bounds
        //Load an image into the shape layer's contents property.
        if let image = UIImage(named: "WareToLogo") {
            shapeLayer.contents = image.cgImage
            layer.addSublayer(shapeLayer)
        }
        let path = UIBezierPath()
        shapeLayer.lineWidth = 2.0
        shapeLayer.strokeColor = UIColor.blue.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        let radius = (bounds.midX + bounds.midY) / 4.0
        path.addArc(withCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
        path.move(to: CGPoint(x:0, y:0))
        path.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
        path.move(to: CGPoint(x: bounds.width, y: 0))
        path.addLine(to: CGPoint(x: 0, y: bounds.height))
        shapeLayer.path = path.cgPath
    }
}

That works, and creates the following when I add an ImageWithShapeView to my project. (I'm using a storyboard, so I implemented UIView.init(coder:) . If you're creating your views in code you'll probably want to implement UIView.init(frame:) instead)

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM