I made a custom NSControl
to use it as a custom layer backed button.
When the MyButton
instance receives mouseDown
and mouseUp
events it changes its backgroundLayer
's backgroundColor
and its textLayer
's foregroundColor
.
It's using layers so the changes are implicitly animated.
But on mouseUp
if the mouse is inside the MyButton
's instance frame I call the linked action through sendAction(_:to:)
method.
I linked the action to a method closing the current window and opening another one but sometimes the app freeze after the second window shows up.
I tried several things and it seems related to the layer animations, maybe something to do before closing the window that I'm not aware of.
You can find an example project here : https://dl.dropboxusercontent.com/u/378166/CALayerFreeze.zip
(note that you'll sometimes have to try several times before the bug occurs)
Here's the code for MyButton
.
class MyButton: NSControl { let title = "Click me!" // Init required init?(coder: NSCoder) { super.init(coder: coder) setup() } deinit { trackingAreas.forEach { self.removeTrackingArea($0) } } // Layer + Tracking Area configuration var backgroundLayer = CALayer() var textLayer = CATextLayer() func setup() { wantsLayer = true backgroundLayer.frame = NSRect(origin: .zero, size: frame.size) backgroundLayer.backgroundColor = NSColor.whiteColor().CGColor layer?.addSublayer(backgroundLayer) textLayer.frame = NSRect(origin: .zero, size: frame.size) textLayer.string = title textLayer.foregroundColor = NSColor.blackColor().colorWithAlphaComponent(0.64).CGColor layer?.addSublayer(textLayer) addTrackingArea( NSTrackingArea( rect: bounds, options: [.MouseEnteredAndExited, .EnabledDuringMouseDrag, .ActiveInKeyWindow], owner: self, userInfo: nil ) ) } // States private func normal() { // ——— COMMENTING THIS MAKES THE BEACHBALL GO AWAY backgroundLayer.backgroundColor = NSColor.whiteColor().CGColor textLayer.foregroundColor = NSColor.blackColor().colorWithAlphaComponent(0.64).CGColor } private func highlight() { // ——— COMMENTING THIS MAKES THE BEACHBALL GO AWAY backgroundLayer.backgroundColor = NSColor.grayColor().CGColor textLayer.foregroundColor = NSColor.whiteColor().colorWithAlphaComponent(0.64).CGColor } // Tracking events var isMouseDown = false override func mouseDown(theEvent: NSEvent) { super.mouseDown(theEvent) isMouseDown = true highlight() } override func mouseUp(theEvent: NSEvent) { super.mouseUp(theEvent) isMouseDown = false normal() if frame.contains(convertPoint(theEvent.locationInWindow, toView: self)) { sendAction(action, to: target) } } }
0 comments:
Post a Comment