将图像添加到 CAShapeLayer Swift 3
Adding image to a CAShapeLayer Swift 3
我正在尝试绘制一个带有分段数组的饼图,每个切片的中心都有一个图像,我已经绘制了饼图,但无法将图像添加到所引用的 cashapelayer.I到以下 post 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){ [=11=] + .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 的任何设置。
几件事:
首先,您只需要在图形更改(调用setNeedsDisplay)或布局更改(viewDidLayoutSubviews)时更新形状图层。你不需要实现 drawRect 除非你真的要画画。分层系统知道如何渲染形状层并将在必要时渲染它。
其次,CAShapeLayer 用于形状。实际上有一大堆 CALayer,它们都绘制不同的东西:https://www.raywenderlich.com/90919/great-calayer-tour-tech-talk-video。对于普通的旧图像,只需执行您的 Objective C 代码正在执行的操作,并使用单独的 CALayer 代替 CAShapeLayer 来保存图像。根据您的 z 顺序首选项,将您的图像层作为子层添加到图形形状层之上或之后。
设置好图层的position属性后,图片就被正确添加到形状图层中了,
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)
我正在尝试绘制一个带有分段数组的饼图,每个切片的中心都有一个图像,我已经绘制了饼图,但无法将图像添加到所引用的 cashapelayer.I到以下 post 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){ [=11=] + .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 的任何设置。
几件事:
首先,您只需要在图形更改(调用setNeedsDisplay)或布局更改(viewDidLayoutSubviews)时更新形状图层。你不需要实现 drawRect 除非你真的要画画。分层系统知道如何渲染形状层并将在必要时渲染它。
其次,CAShapeLayer 用于形状。实际上有一大堆 CALayer,它们都绘制不同的东西:https://www.raywenderlich.com/90919/great-calayer-tour-tech-talk-video。对于普通的旧图像,只需执行您的 Objective C 代码正在执行的操作,并使用单独的 CALayer 代替 CAShapeLayer 来保存图像。根据您的 z 顺序首选项,将您的图像层作为子层添加到图形形状层之上或之后。
设置好图层的position属性后,图片就被正确添加到形状图层中了,
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)