Discrepancy using CAAnimation on 10.5 vs 10.6

Discussion in 'Mac Programming' started by Littleodie914, Nov 2, 2010.

  1. macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #1
    Hey guys, I have the following sections of code that I use to fade out a modal window:

    Code:
    - (IBAction)open:(id)sender {
    	if ([self alphaValue] < 1.0) {
    		[self setAlphaValue:1.0];
    	}
    	[self showDevicesViews];
    	[self start];
    	[NSApp runModalForWindow:self];
    	NSLog(@"runModalForWindow: returned");
    	[super orderOut:nil];
    }
    
    - (void) animationDidEnd:(NSAnimation *)animation {
    	NSLog(@"animationDidEnd:");
    }
    
    - (void)animationDidStop:(NSAnimation *)animation {
    	NSLog(@"animationDidStop:");
    }
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    	NSLog(@"animationDidStop:finished:");
    	[NSApp stopModal];
    }
    
    - (void)orderOut:(id)sender {
    	NSLog(@"self orderOut:");
    	[self stop];
    	CAAnimation *anim = [CABasicAnimation animation];
    	[anim setDelegate:self];
    	[anim setDuration:0.2];
    	[self setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"alphaValue"]];
    	[[self animator] setAlphaValue:0.0];
    }
    The issue in a nutshell is that on 10.5, the window never fades out, or even closes. On 10.6, everything works fine.

    On 10.6, I see in the console:

    Code:
    11/2/10 10:25:51 AM	Application[204]	self orderOut:
    11/2/10 10:25:51 AM	Application[204]	animationDidStop:finished:
    11/2/10 10:25:52 AM	Application[204]	runModalForWindow: returned
    On 10.5, all I see is:

    Code:
    11/2/10 10:27:31 AM	Application[204]	self orderOut:
    
    I've read through the documentation for CAAnimation, etc. but I can't find anything that would suggest the behavior for running animations and calling delegate methods would differ between operating system versions.

    Am I missing something? Is there a more elegant/proper way to fade out a modal window? I would like to use the "official" method, as opposed to putting together a workaround. Thanks! :D
     
  2. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #2
    (I really only know CocoaTouch)

    First off, what are you subclassing?

    What is -start and -stop supposed to accomplish? Are they similar to UIAlertView's -show and -dismissWithClickedButtonIndex:animated: ??


    If so, possibly move [self stop]; to be after the animation.
     
  3. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #3
    I'm subclassing NSPanel.

    Start and stop are used for purposes unrelated to the panel's lifecycle, they actually stop listening for bonjour services on the network.

    It's definitely an issue with the animation delegate method not being properly called. If I remove the animation code to read:

    Code:
    - (void)orderOut:(id)sender {
    	NSLog(@"self orderOut:");
    	[self stop];
    	[NSApp stopModal]; [B]// New Line[/B]
    	/* [B] <- Start Comment [/B]
    	CAAnimation *anim = [CABasicAnimation animation];
    	[anim setDelegate:self];
    	[anim setDuration:0.2];
    	[self setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"alphaValue"]];
    	[[self animator] setAlphaValue:0.0];
    	 */ [B] <- End Comment [/B]
    }
    Then the window closes properly on 10.5.
     
  4. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #4
    When you created and displayed your panel did you -setWorksWhenModal: YES??
     
  5. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #5
    Yep, double-checked, but still no go. :(
     
  6. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #6
    Check that [self animator] returns an actual object.

    EDIT meaning something like NSLog(@"%@", [self animator]); say.. right after the NSLog(@"self ourderOut:");
    EDIT2 also, it couldn't hurt to do [self setAlphaValue: 1.0]; around the same time.
    EDIT3 is your panel interface explicitly SAY it implements whatever delegate protocol is used here. Maybe that is something Apple could have changed in the implementation of the CAAnimation stuff when going from 10.5 -> 10.6
    Maybe in 10.5 the call back methods use -conformsToProtocol: and in 10.6 they uses -respondsToSelector: for each method. That would explain what we are seeing here most succinctly.
     
  7. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #7
    Few things to try:

    - Override +defaultAnimationForKey: and return your CABasicAnimation instance there.
    - Use NSAnimationContext instead. You don't get the delegate callback but easy to workaround with a timer.
    - Use NSTimer, add it to NSEventTrackingRunLoopMode and NSModalPanelRunLoopMode and call setAlphaValue: repeatedly.
     
  8. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #8
    I'll test this and get back to you in a second. (I have both 10.5 and 10.6 on the same machine, have to reboot.)

    Edit: No dice. On 10.6:

    Code:
     2010-11-02 15:02:46.335 Application[254:a0f] self orderOut:
    2010-11-02 15:02:46.337 Application[254:a0f] animator: <_NSWindowAnimator_SyncPanel: 0x177750> Animator Proxy for: {
    <SyncPanel: 0x124fc0>
    }
    2010-11-02 15:02:46.540 Application[254:a0f] animationDidStop:finished:
    2010-11-02 15:02:47.153 Application[254:a0f] runModalForWindow: returned
    
    And on 10.5 (just noticed my timezone is messed up... crappy dual boot):

    Code:
    11/2/10 12:16:09 PM Application[100] self orderOut: 
    11/2/10 12:16:09 PM Application[100] animator: <_NSWindowAnimator_SyncPanel: 0x1be9f0> Animator Proxy for: {
    <SyncPanel: 0x15f8b0>
    }
    
    As far as I can tell, there is no formal protocol. You just set the delegate on the animation, then implement the proper methods. I'm not even sure where I found reference of the animationDidStop:finished: method. :confused:

    Documentation (May Require Login)
     
  9. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #9
    Attached is a simple project demonstrating the issue. I can confirm the window closes on 10.6, but does not on 10.5.
     

    Attached Files:

  10. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #10
    I assume you tried my EDIT2 solution as well?'

    EDIT: I have no machines running 10.5, not even sure any of my machines CAN run 10.5 at this point.
     
  11. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #11
    I have tried your EDIT2 solution, but unfortunately it didn't help.

    I had to partition my hard drive and whip out my old restore CDs to install Leopard.

    I was actually having a friend test the application last night, and her laptop only has 10.5. Since the modal window never closes, she ended up having to force quit the app. :eek: Good thing we found it though! I had assumed things would behave the same on 10.5 and 10.6, guess it was a foolish assumption to make.
     
  12. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #12
    I played around a bit. Definitely related to the modal run loop. Somehow the animation is just not going through. I tried with NSAnimationContext and a timer but no luck.

    I would either drop the animation for 10.5 since most people are on 10.6 now or switch to NSTimer where you have much more control.
     
  13. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #13
    I have made some changes to your source, you now hit a button {setup} before firing the animation. See if it helps. I wish I had a computer running 10.5 to test with. Maybe I can install something on one of my spare hack boxes around here....
     

    Attached Files:

  14. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #14
    "On 10.5, NSView and NSWindow property animations that were scheduled through the view’s/window’s “animator”, and that were evaluated by AppKit (rather than being delegated to Core Animation for threaded asynchronous evaluation), were scheduled for updating in the NSDefaultRunLoopMode.
    On 10.6, such animations are now evaluated in NSRunLoopCommonModes."
     
  15. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #15
    Where did you find mention of this? Very interesting.

    Also, not to sound stupid, but what exactly does that mean? :) I have no experience with the different run loops.

    Edit: Also, I appreciate the modified project, but it still has the same behavior as the original under 10.5. :(
     
  16. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #16
    As expected given that I didn't find out about the run loop thing until after making some changes.

    I have fixed the project more appropriately. Using NSViewAnimation in blocking mode.

    I HOPEEEEEEE this works in 10.5...... Probably even 10.4 ;)
     

    Attached Files:

  17. thread starter macrumors 68000

    Littleodie914

    Joined:
    Jun 9, 2004
    Location:
    Rochester, NY
    #17
    You, sir, are a gentleman and a scholar. Works perfectly in 10.5 and 10.6. :)

    It seems strange (confusing?) that there are so many different ways to accomplish the same thing. (NSViewAnimation, CABasicAnimation, the animator layer, etc.)

    Anyway, I'll sleep well tonight. Thanks again. :D
     
  18. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #18
    Nice jared. Forgot about NSViewAnimation. Indeed, many ways to go about this :)
     
  19. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #19
    Great, glad it worked out. I certainly learned some things (again I'm only really familiar with iOS UI Classes), so good times by all.

    I'm also glad apple "fixed" it themselves in 10.6 but wish they had made a 10.5 point release that would have fixed it there too.
     

Share This Page