将图像添加到CAShapeLayer Swift 3

5
我正在尝试使用分段数组和每个切片中心的图像绘制饼图,我已经成功绘制了饼图,但是无法将图像添加到CAShapeLayer中。我参考了以下帖子Swift: Add image to CAShapeLayer,但它并没有解决我的问题。
这是我尝试过的内容。
override func draw(_ rect: CGRect) {
        //let context = UIGraphicsGetCurrentContext()
        let radius = min(frame.size.width,frame.size.height) * 0.5;
        let viewCenter = CGPoint(x: frame.size.width * 0.5, y: frame.size.height * 0.5)
        let valueCount = segments.reduce(0){ $0 + $1.value}
        var startAngle = -CGFloat(M_PI / 2)

        for segment in segments {
           let endAngle = startAngle + CGFloat(M_PI * 2) * (segment.value)/valueCount

            /*context?.move(to: CGPoint(x: viewCenter.x, y: viewCenter.y))
            context?.setFillColor(segment.color.cgColor)
            context?.setStrokeColor(UIColor.black.cgColor)
            context?.setLineWidth(3.0)
            context?.addArc(center: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
            context?.fillPath()*/

            let pieSliceLayer = CAShapeLayer()
            let slicePath = UIBezierPath(arcCenter: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
            pieSliceLayer.path = slicePath.cgPath
            pieSliceLayer.fillColor = segment.color.cgColor
            self.layer.addSublayer(pieSliceLayer)

            let halfAngle = startAngle + (endAngle - startAngle) * 0.5;
            let imagePositionValue = CGFloat(0.67)
            let segmentCenter = CGPoint(x:viewCenter.x+radius*imagePositionValue*cos(halfAngle),y:viewCenter.y+radius*imagePositionValue*sin(halfAngle))

            //If image is associated , add the image to the section
            let imageLayer = CAShapeLayer()
            let image = UIImage(named: segment.imageName)
            imageLayer.contents = image?.ciImage
            imageLayer.frame = CGRect(x: segmentCenter.x - 20, y: segmentCenter.y - 20, width: 20, height: 20)
            self.layer.addSublayer(imageLayer)
            startAngle = endAngle

        }
    }

我在objective-C中尝试了类似的东西,它可以正常工作,

CALayer *imageLayer = (CALayer *)[[pieLayer sublayers] objectAtIndex:0];
    //Adding image
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [[UIColor clearColor] CGColor];
    layer.bounds = CGRectMake(imageLayer.bounds.origin.x +20 ,
                                  imageLayer.bounds.origin.y + 20, 15, 15);
    NSString *imageName = [NSString stringWithString:[[self.goalSettingsModel objectAtIndex:value] valueForKeyPath:@"imageName"]];
    layer.contents =  (id)[UIImage imageNamed:imageName].CGImage;
    [imageLayer addSublayer:layer];
    [imageLayer setNeedsDisplay];

我不确定是否错过了calayer的任何设置。


嗨,我尝试以与Objective-C片段相同的方式进行操作,为了计算弧形路径的中心点,我正在使用以下代码,但我仍然看不到图像,让boundingBox = pieSliceLayer.path?.boundingBox,然后centerPoint = CGPoint(x:(boundingBox?.origin.x)! + (boundingBox?.size.width)!/2,y:(boundingBox?.origin.y)!+(boundingBox?.size.height)!/2)。 - Vinodha Sundaramoorthy
2个回答

8

在为图层设置位置属性后,将图像成功添加到形状图层中。

let imageLayer = CALayer()
imageLayer.backgroundColor = UIColor.clear.cgColor
imageLayer.bounds = CGRect(x: centerPoint.x, y: centerPoint.y , width: 15, height: 15)
imageLayer.position = CGPoint(x:centerPoint.x ,y:centerPoint.y)
imageLayer.contents = UIImage(named:segment.imageName)?.cgImage
self.layer.addSublayer(pieSliceLayer)
self.layer.addSublayer(imageLayer)

2
一些事情:
首先,只有当图形发生更改(调用setNeedsDisplay)或布局更改(viewDidLayoutSubviews)时,您才需要更新形状层。除非您要进行实际绘制,否则不需要实现drawRect。分层系统知道如何呈现形状层,并将根据需要呈现它。
其次,CAShapeLayer用于形状。实际上有许多CALayer,它们都绘制不同的内容:https://www.raywenderlich.com/90919/great-calayer-tour-tech-talk-video。对于普通的图像,只需执行您的Objective C代码正在执行的操作,并使用单独的CALayer来保存图像,而不是CAShapeLayer。根据您的z-ordering偏好,在图形形状层之上或之下添加图像层作为子层。

谢谢提供视频链接,非常有用。我通过设置CALayer的位置来解决了问题。let imageLayer = CALayer() imageLayer.backgroundColor = UIColor.clear.cgColor imageLayer.bounds = CGRect(x: centerPoint.x, y: centerPoint.y , width: 15, height: 15) imageLayer.position = CGPoint(x:centerPoint.x ,y:centerPoint.y) imageLayer.contents = UIImage(named:segment.imageName)?.cgImage self.layer.addSublayer(pieSliceLayer) self.layer.addSublayer(imageLayer) - Vinodha Sundaramoorthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接