ZbadhabitZ ZbadhabitZ - 4 months ago 22
Swift Question

Converting a CAShapeLayer to use in an NSImageView

I'm trying to port some iOS code for a Mac app. My code is as follows:

func innerRing() {
let innerRing = CAShapeLayer()
let circleRadius: CGFloat = 105.0
innerRing.frame = InnerRingView.bounds

func circleFrame() -> CGRect {
var circleFrame = CGRect(x: 0, y: 0, width: 2*circleRadius, height: 2*circleRadius)
circleFrame.origin.x = CGRectGetMidX(InnerRingView.bounds) - CGRectGetMidX(circleFrame)
circleFrame.origin.y = CGRectGetMidY(InnerRingView.bounds) - CGRectGetMidY(circleFrame)
return circleFrame
}

innerRing.path = UIBezierPath(ovalInRect: circleFrame()).CGPath
innerRing.lineWidth = 3.0
innerRing.strokeStart = 0.0
innerRing.strokeEnd = 1.0
innerRing.fillColor = UIColor.clearColor().CGColor
innerRing.strokeColor = UIColor(red: 147.0/255.0, green: 184.0/255.0, blue: 255.0/255.0, alpha: 1.0).CGColor
InnerRingView.layer.addSublayer(innerRing)
}


This code works very well, especially for adjusting the fill color, stroke color, and stroke start/end.

In my Mac app, I am effectively trying to use the same code, but apply it to an
NSImageView
(I want it to be able to appear on each row of a table, and I will adjust certain parameters (such as color) based on what that row details.

Could anyone assist with guidance on adding this simple circle to an
NSImageView
?

Answer

Why do you want to use an NSImageView? NSImageView is for displaying images (icons, pictures, etc).

Make yourself a custom NSView instead. Just remember that, unlike UIKit's UIView, NSView doesn't get a layer by default, so you need to tell It to by setting wantsLayer to true.

Like so:

class CircleView: NSView {

    lazy var innerRing: CAShapeLayer = {
        let innerRing = CAShapeLayer()
        let circleRadius: CGFloat = 105.0
        innerRing.frame = self.bounds

        var circleFrame = CGRect(x: 0, y: 0, width: circleRadius, height: circleRadius)
            circleFrame.origin.x = CGRectGetMidX(self.bounds) - CGRectGetMidX(circleFrame)
            circleFrame.origin.y = CGRectGetMidY(self.bounds) - CGRectGetMidY(circleFrame)

        innerRing.path = CGPathCreateWithEllipseInRect(circleFrame, nil)
        innerRing.lineWidth = 3.0
        innerRing.strokeStart = 0.0
        innerRing.strokeEnd = 1.0
        innerRing.fillColor = NSColor.clearColor().CGColor
        innerRing.strokeColor = NSColor(red: 147.0/255.0, green: 184.0/255.0, blue: 255.0/255.0, alpha: 1.0).CGColor
        return innerRing
    }()

    override func awakeFromNib() {
        super.awakeFromNib()

        wantsLayer = true
        layer = CALayer()
        layer?.addSublayer(innerRing)
    }

}