我有一个填充颜色的CAShapeLayer,并希望在此形状的中心添加一个图标:
I have a CAShapeLayer with a fill color, and want to add an icon in the center of this shape:
var shape = CAShapeLayer() shape.fillColor = UIColor(white: 0.90, alpha: 1).CGColor var image = UIImage(named: "some_image") shape.contents = image?.CGImage此代码确实编译并显示灰色形状 - 但没有图像。 :(
This code does compile and does show the grey shape- but no image. :(
我调查过这些帖子,但我不能像他们那样投射CGImage。
I looked into these posts, but I can't cast the CGImage like they do.
在CALayer中添加UIImage 和使用普通CALayer显示图像或UIImage
是还有另外一种方法吗?或者修改了id?
Is there another way? Or a workaround to the id cast?
完整代码:
ViewController。 swift
import UIKit class ViewController: UIViewController { @IBOutlet var menuView: UIView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func viewDidAppear(animated: Bool) { let menu: CircularMenu = CircularMenu(frame: menuView.bounds, numberOfMenuItems: 4, hasProgressBar: false) self.menuView.addSubview(menu) } }CircularMenu.swift
import UIKit // *** Helper methods start func DegreesToRadians (value: Double) -> CGFloat { return CGFloat(value * M_PI / 180.0) } func RadiansToDegrees (value: Double) -> CGFloat { return CGFloat(value * 180.0 / M_PI) } // *** Helper methods end class CircularMenu: UIControl { var parent: UIViewController! var centerButton: UIButton! var menuButtonShapes = [CAShapeLayer]() var menuButtons = [UIButton]() var numberOfButtons: Double = 4 var bigSize: CGFloat = 300 var centerButtonSize: CGFloat = 100 var centerButtonPadding: CGFloat = 70 let paddingBetweenButtons = 1 required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override init(frame: CGRect) { super.init(frame: frame) } convenience init(frame: CGRect, numberOfMenuItems: Int, hasProgressBar: Bool = false) { self.init(frame: frame) self.bounds = frame self.bigSize = frame.width self.centerButtonSize = bigSize/2 self.centerButtonPadding = bigSize/4-5 if hasProgressBar { self.centerButtonSize -= 10 } if numberOfMenuItems != 0 && numberOfMenuItems <= 10 { self.numberOfButtons = Double(numberOfMenuItems) } // Draw center button var centerButtonView = UIView(frame: CGRectMake(0, 0, centerButtonSize, centerButtonSize)) centerButtonView.backgroundColor = UIColor(red: 160.0/255, green: 197.0/255, blue: 25.0/255, alpha: 1) centerButtonView.center = self.center; centerButtonView.layer.cornerRadius = centerButtonSize/2 self.addSubview(centerButtonView) self.centerButton = UIButton(frame: centerButtonView.bounds) let degreesPerButton: Double = 360.0/numberOfButtons // Draw button shapes for (var i: Double = 1; i <= numberOfButtons; i++) { // Determine start and end radians of pizza slice let startAngle = DegreesToRadians(degreesPerButton*i+degreesPerButton-Double(paddingBetweenButtons)) let endAngle = DegreesToRadians(degreesPerButton*i+Double(paddingBetweenButtons)) // Determine center and angle of slice var buttonCenter = self.center; var offsetDirection = (startAngle - endAngle)/2 + endAngle // Shove slice outward to make space for inner padding var offsetX = cos(offsetDirection)*tan(DegreesToRadians(Double(paddingBetweenButtons)))*bigSize/2 var offsetY = sin(offsetDirection)*tan(DegreesToRadians(Double(paddingBetweenButtons)))*bigSize/2 buttonCenter.x += offsetX buttonCenter.y += offsetY // Create mask for outer rim of slice to a circular form (from triangle to pizza slice) let outerCircleRadius = bigSize/2; var bigCircle = UIBezierPath(arcCenter: self.center, radius: bigSize/2, startAngle: startAngle , endAngle: endAngle, clockwise: false); bigCircle.addLineToPoint(buttonCenter) bigCircle.closePath() // Take padding into consideration when creating mask let tmpBigSizeX = (bigSize+2*abs(offsetX)) let tmpBigSizeY = (bigSize+2*abs(offsetY)) // Create mask for inner rim of slice to a circular form (from pizza slice to donut slice) let smallSize = bigSize-centerButtonSize-centerButtonPadding let innerCircleRadius = outerCircleRadius-bigSize/2/2; var smallCircle = UIBezierPath(arcCenter: self.center, radius: smallSize, startAngle: 0 , endAngle: DegreesToRadians(360), clockwise: false); // Apply masks for everything but the donut slice shape var buttonShape = CAShapeLayer() var maskLayer = CAShapeLayer() var maskPath = CGPathCreateMutable(); CGPathAddRect(maskPath, nil, CGRectMake(outerCircleRadius-tmpBigSizeX/2, outerCircleRadius-tmpBigSizeY/2, tmpBigSizeX, tmpBigSizeY)); CGPathAddPath(maskPath, nil, smallCircle.CGPath); maskLayer.path = maskPath; maskLayer.fillRule = kCAFillRuleEvenOdd; buttonShape.path = bigCircle.CGPath buttonShape.mask = maskLayer buttonShape.fillColor = UIColor(white: 0.90, alpha: 1).CGColor // Add icons and labels to the button var image = UIImage(named: "menu-icon_users_grey") let imageSubLayer = CALayer() imageSubLayer.contents = image?.CGImage buttonShape.addSublayer(imageSubLayer) // Save references to both shape and button self.menuButtons.append(UIButton(frame: buttonShape.frame)) self.menuButtonShapes.append(buttonShape) // Add shape to view self.layer.addSublayer(buttonShape) } } }感兴趣的行位于评论下的自定义UIControl的底部:
Lines of interest are in the bottom of the custom UIControl under the comment:
为按钮添加图标和标签
推荐答案你有两个选择:
不太好的,用一种颜色转换UIImage然后将它转换为CGColor,但由于你的代码片段很小,我不知道它会起作用:
The not-so-good one, transform the UIImage in a color and then cast it to CGColor, but since your code snippet is so small, I don't know what is going to work:
let image = UIImage(named: "") if let realImage = image { let color = UIColor(patternImage: realImage) shape.fillColor = color.CGColor }推荐的一个,创建一个新图层并在其内容上设置UIImage:
And the recommended one, create a new layer and set the UIImage on its contents:
let imageSubLayer = CALayer() imageSubLayer.contents = image?.CGImage shape.addSublayer(imageSubLayer)我现在无法测试,所以告诉我它是否有效。
I can't test it right now, so tell me if it works.
更多推荐
Swift:将图像添加到CAShapeLayer
发布评论