Reputation: 14168
I created an icon in PaintCode that is drawn programmatically (but this question isn't necessarily specific to that tool) and I'm trying to get that icon to redraw.
I use a custom class like this:
class IconTabGeneral: NSView {
override func draw(_ dirtyRect: NSRect) {
StyleKitMac.drawTabGeneral()
}
}
The drawTabGeneral()
is a method in the StyleKitMac
class (generated by PaintCode) that looks like this (I'll omit all the bezierPath
details):
@objc dynamic public class func drawTabGeneral(frame targetFrame: NSRect = NSRect(x: 0, y: 0, width: 22, height: 22), resizing: ResizingBehavior = .aspectFit) {
//// General Declarations
let context = NSGraphicsContext.current!.cgContext
//// Resize to Target Frame
NSGraphicsContext.saveGraphicsState()
let resizedFrame: NSRect = resizing.apply(rect: NSRect(x: 0, y: 0, width: 22, height: 22), target: targetFrame)
context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
context.scaleBy(x: resizedFrame.width / 22, y: resizedFrame.height / 22)
//// Bezier Drawing
let bezierPath = NSBezierPath()
...
bezierPath.close()
StyleKitMac.accentColor.setFill() ⬅️Custom color set here
bezierPath.fill()
NSGraphicsContext.restoreGraphicsState()
}
The accentColor
defined there is a setting that can be changed by the user. I can't get my instance of IconTabGeneral
to redraw to pick up the new color after the user changes it.
I've tried this without any luck:
iconGeneralTabInstance.needsDisplay = true
My understanding is that needsDisplay
would force the draw
function to fire again, but apparently not.
Any idea how I can get this icon to redraw and re-fill its bezierPath
?
Upvotes: 1
Views: 232
Reputation: 14168
I think I got it. It turns out the PaintCode-generated StyleKitMac
class was caching the color. The icon was, in fact, being redrawn after needsDisplay
was being set. So I just had to refresh the cache's color value.
Upvotes: 1
Reputation: 9493
How about using a NSImageView
? Here is a working example:
import AppKit
enum StyleKit {
static func drawIcon(frame: CGRect) {
let circle = NSBezierPath(ovalIn: frame.insetBy(dx: 1, dy: 1))
NSColor.controlAccentColor.setFill()
circle.fill()
}
}
let iconView = NSImageView()
iconView.image = .init(size: .init(width: 24, height: 24), flipped: true) { drawingRect in
StyleKit.drawIcon(frame: drawingRect)
return true
}
import PlaygroundSupport
PlaygroundPage.current.liveView = iconView
Upvotes: 1