简体   繁体   中英

Animation on NSCell

I'm trying to animate some of the cells in my NSOutlineView. I need to animate an icon to rotate as the iTunes syncing icon next to the device, on the left panel.

I'm not really experienced in the animating field, I found this simple solution by looking all over the internet:

- (void)startAnimation:(CALayer *)layer {    
    CABasicAnimation *spinAnimation = (CABasicAnimation *)[layer animationForKey:@"spinAnimation"];
    if (!spinAnimation) {
        spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        spinAnimation.toValue = [NSNumber numberWithFloat:-(5*2*M_PI)];
        spinAnimation.duration = 10;
        spinAnimation.repeatCount = 10000;
        [spinAnimation setRemovedOnCompletion:YES];
        [spinAnimation setSpeed:2.0f];
        [layer addAnimation:spinAnimation forKey:@"spinAnimation"];    
    }
}

The problem I'm having with this solution is that neither of the different subclasses of NSCell has a CALayer that I can work with. So at first I've decided to subclass NSCell adding an NSImageView that contains an CALayer. The animation worked, but the experience was awful, the image view was incredibly inefficient, I could barely scroll and the animation only worked in one of the rows.

What I'm trying to do now is subclass NSButtonCell (I'll need to set an action to the cell, otherwise it would've been an NSImageCell), override the drawWithFrame method and add a subLayer to the NSView (controlView) received and then animate it.

The problem right now is that the animation won't work.

I leave you the code.

PLZ HELP..

- (void)setObjectValue:(id<NSCopying>)obj {
    @try {        
        [super setImage:[NSImage imageNamed:@"syncImage.png"]];
        [super setObjectValue:nil];        
    }
    @catch (NSException *exception) {
        NSLog(@"CustomImageViewCell-setObjectValue: %@", [exception description]);       
        [self setImage:nil];
        [super setObjectValue:nil];           
    }    
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    [super drawWithFrame:cellFrame inView:controlView];
    if (![controlView layer]) {
        CALayer *layer = [CALayer layer];
        [layer setFrame:[controlView frame]];
        [controlView setLayer:layer];
    }

    CALayer *layer = [CALayer layer];
    [layer setFrame:cellFrame];
    [[controlView layer] addSublayer:layer];    

    [self startAnimation:layer];    
}

Thanks in advance.

Mikywan.

Edit: This answer only works for use in iOS -- Original Question is for use in OSX


I would suggest using UIImageView 's animationImages and animationDuration properties. (I believe that this is essentially what Apple does for their UIActivityIndicator class.) This should be cheaper/perform better than constantly recalculating the rotated image.

So, use an image editor and save out multiple "frames" of your icon in sequential rotated positions, and use those to populate an array for the animationImages property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM