开发者

Can't get [[id Animator] setAlphaValue: 0.0] to work

I'm trying to animate an opacity fade out + frame size change of an NSImageView . The frameSize works smoothly but for some reason the alpha value just jumps directly to it's final value at the beginning of the animation. I've tried back layering the superview and I'm running 开发者_JAVA技巧out of ideas here. Here is my code sample ->

AABLCLogo   -> NSImageView IBOutlet
speed       -> 1.0f 

//setting target frame for image view

NSRect newFrame      = [AABLCLogo frame];
newFrame.origin.x    = newFrame.origin.x + (newFrame.size.width*0.1);
newFrame.origin.y    = newFrame.origin.y + (newFrame.size.height*0.1);
newFrame.size.width  = newFrame.size.width * 0.8;
newFrame.size.height = newFrame.size.height * 0.8;

//backing layer for super view

[[AABLCLogo superview] setWantsLayer:YES];

//animating image view

[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration: speed];
[[AABLCLogo animator] setFrame: newFrame];
[[AABLCLogo animator] setAlphaValue: 0.0];
[NSAnimationContext endGrouping];

//XCode 4 delay snippet

double delayInSeconds   = speed;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 
                                        delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, 
               dispatch_get_main_queue(), 
               ^(void) {

    //code executes after ''speed'' seconds

    [[AABLCLogo superview] setWantsLayer:NO];
    [[self view] removeFromSuperview];

                });


I suspect this is an issue with animating on the main thread. In most cases, if you want to animate two things simultaneously, you'll need to use NSViewAnimation. Use this code as a guide, it resizes the window while fading out part of it's content.

NSRect newWindowFrame = NSMakeRect(self.window.frame.origin.x, self.window.frame.origin.y, 640, self.window.frame.size.height);
NSMutableArray *viewAnimations = [NSMutableArray array];
NSDictionary *windowSizeDict = [NSDictionary dictionaryWithObjectsAndKeys:self.window, NSViewAnimationTargetKey, [NSValue valueWithRect:newWindowFrame], NSViewAnimationEndFrameKey, nil];
[viewAnimations addObject:windowSizeDict];

NSDictionary *animateOutDict = [NSDictionary dictionaryWithObjectsAndKeys:self.dataSidebarController.containerView, NSViewAnimationTargetKey, NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey, nil];
[viewAnimations addObject:animateOutDict];

NSViewAnimation *animation = [[NSViewAnimation alloc] initWithViewAnimations:viewAnimations];
[animation setDuration:0.35];
[animation setAnimationBlockingMode:NSAnimationNonblocking];
[animation setDelegate:self];
[animation startAnimation];


You want to send setWantsLayer:YES to the view you are animating, not its superview.

NSView's setAlphaValue: only works an a layer-backed or layer-hosting instance, since it forwards the value to the opacity property of NSView's layer.

For the full story, read the "Discussion" of NSView's setAlphaValue: in Apple's documentation.


I believe the layer you request is not create until the next time the view is drawn.

Thus you either need to force display of the superview or wait until the next iteration of the run loop before adding on animations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜