Reputation: 5283
I am trying to animate my NSWindow after I click a specific button, so I wrote a function:
func fadeIn(window: NSWindow, duration: NSTimeInterval) {
var alpha = 0.0 as CGFloat
window.alphaValue = alpha
window.makeKeyAndOrderFront(nil)
let numberOfLoops = Int(duration / 0.02)
let alphaChangeInLoop = (CGFloat(1.0) / CGFloat(numberOfLoops))
var loopRun = 0
for _ in 0...numberOfLoops {
loopRun += 1
alpha += alphaChangeInLoop
window.alphaValue = alpha
NSThread.sleepForTimeInterval(0.020)
}
print("Loop was run \(loopRun) times. Ending alpha: \(alpha)")
if alpha != 1.0 {
alpha = 1.0
window.alphaValue = 1.0
print("Alpha set to 1.0")
}
}
It seems OK for me, but it is not - the window does not fade in. It just appears after whatever I put in the duration field (so it is probably not accepting any alphaValue below 1.0).
Is it possible to animate alphaValue in OSX application? I've been searching this forum and I found some other ways including NSAnimationContext but it did not work for me.
Upvotes: 4
Views: 2567
Reputation: 90551
The problem with your approach is that the window typically only redraws when you let flow of execution return to the main event loop. You're not doing that until the end. You could try to force the window to redraw for each iteration of your loop, but don't bother.
Animation is built in to Cocoa. Try this:
window.alphaValue = 0
window.makeKeyAndOrderFront(nil)
NSAnimationContext.runAnimationGroup({ (context) -> Void in
context.duration = duration
window.animator().alphaValue = 1
}, completionHandler: nil)
If you're OK with the default duration of 0.25 seconds, you can just do:
window.alphaValue = 0
window.makeKeyAndOrderFront(nil)
window.animator().alphaValue = 1
You should also be aware that Cocoa applies animations to windows, by default. You should consider just letting it do its thing. If you insist on taking over for it, you should probably do:
window.animationBehavior = .None
Upvotes: 10