J'ai un CAShapeLayer avec une couleur de remplissage, et que vous souhaitez ajouter une icône dans le centre de cette forme:Swift: Ajouter une image à CAShapeLayer
var shape = CAShapeLayer()
shape.fillColor = UIColor(white: 0.90, alpha: 1).CGColor
var image = UIImage(named: "some_image")
shape.contents = image?.CGImage
Ce code ne compile et ne montre la forme- gris, mais pas d'image. :(
J'ai regardé dans ces messages, mais je ne peux pas jeter le CGImage comme ils le font.
add UIImage in CALayer et Display an image or UIImage with a plain CALayer
Y at-il une autre façon? Ou une solution à la distribution id?
code complet:
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)
}
}
}
Lignes d'intérêt sont en bas de l'UIControl personnalisé sous le commentaire:
"Ajouter des icônes et des étiquettes sur le bouton"
Pourquoi pensez-vous que la couche dessine l'image sur la couleur de remplissage? Essayez d'ajouter une sous-couche à cette couche et ajoutez l'image à cela. – Jack
Non, j'ai essayé mais il n'est toujours pas dessiné ... :( – Anfaje
Pouvez-vous montrer le code que vous utilisez? Il n'y a pas de raison pour cela de ne pas dessiner.Pour CALayers, vous devez définir les limites de façon appropriée – Jack