Macos 尝试使用CAAnimation和CATextLayer滑动文本

Macos 尝试使用CAAnimation和CATextLayer滑动文本,macos,core-animation,calayer,quartz-graphics,caanimation,Macos,Core Animation,Calayer,Quartz Graphics,Caanimation,我正在尝试使用CATextLayer在视图中滑动文本,但显然不起作用: 函数animationDidStop:finished:被调用一次,但没有as标志值 代码(NSView子类): 提前谢谢你, ief2我更改了代码,但没有调试以前的代码 新的实现,如果有人想看到它: #import "AppStatusItemView.h" #define DEFAULT_FRAME (NSMakeRect(0 , 0 , 140 , 20)) #define SLIDE_SPEED (30.0) /*


我正在尝试使用CATextLayer在视图中滑动文本,但显然不起作用:

函数
animationDidStop:finished:
被调用一次,但没有as
标志

代码(NSView子类):

提前谢谢你,

ief2

我更改了代码,但没有调试以前的代码

新的实现,如果有人想看到它:

#import "AppStatusItemView.h"

#define DEFAULT_FRAME (NSMakeRect(0 , 0 , 140 , 20))
#define SLIDE_SPEED (30.0) /* points per second */

/* ============================================================================
 MARK: -
 MARK: Private Interface
 =========================================================================== */
@interface AppStatusItemView (Private)
- (void)slide;
- (NSTimeInterval)intervalWithWidth:(CGFloat)w speed:(CGFloat)s;
@end

/* ============================================================================
 MARK: -
 MARK: Public Implementation
 =========================================================================== */
@implementation AppStatusItemView
/* MARK: Init */
- (id)initWithText:(NSString *)pS {
    self = [self initWithFrame:DEFAULT_FRAME];
    if(self != nil) {
        _text = [pS retain];

        /* Create root layer */
        {
            //CGColorRef myColor = CGColorCreateGenericRGB(0.5 , 0.0 , 0.0 , 0.5);
            _rootLayer = [[CAScrollLayer layer] retain];
            [_rootLayer setFrame:NSRectToCGRect([self bounds])];
            //[_rootLayer setBackgroundColor:myColor];
            [self setWantsLayer:YES];
            [self setLayer:_rootLayer];
            //CGColorRelease(myColor);
        }

        /* Create text layer */
        {
            CGColorRef myColor = CGColorCreateGenericRGB(0.0 , 0.0 , 0.0 , 1.0);
            _textLayer = [[CATextLayer layer] retain];
            [_textLayer setFontSize:12.0];
            [_textLayer setForegroundColor:myColor];
            [self slide];
            CGColorRelease(myColor);
        }

    }
    return self;
}

- (void)dealloc {
    [_text release];
    [_textLayer release];
    [_rootLayer release];
    [super dealloc];
}

/* MARK: Properties */ 
@synthesize text=_text;
- (void)setText:(NSString *)pT {
    if(![_text isEqualToString:pT]) {
        [_text release];
        _text = [pT retain];
    }
}

/* MARK: Animation Delegate */
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    if(flag) {
        [self slide];
    }
}
@end

/* ============================================================================
 MARK: -
 MARK: Private Implementation
 =========================================================================== */
@implementation AppStatusItemView (Private)
- (void)slide {
    NSRect startFrame, endFrame;
    NSPoint startPosititon, endPosition;
    NSSize textSize;

    [_textLayer removeFromSuperlayer];

    /* Set start frame and position */
    {
        NSDictionary *attributes;
        NSFont *font;
        CGFloat h;

        font = [NSFont fontWithName:@"Helvetica" 
                               size:12.0];
        attributes = [NSDictionary dictionaryWithObject:font 
                                                 forKey:NSFontAttributeName];
        textSize = [_text sizeWithAttributes:attributes];

        h = ([self bounds].size.height - textSize.height) / 2.0;
        startFrame = NSMakeRect([self bounds].size.width,
                                h, textSize.width , textSize.height);
        startPosititon.x = [self bounds].size.width + textSize.width / 2.0;
        startPosititon.y = [self bounds].size.height / 2.0;

        [_textLayer setString:_text];
        [_textLayer setFrame:NSRectToCGRect(startFrame)];
        [_textLayer setPosition:NSPointToCGPoint(startPosititon)];
    }

    /* Slide to end position */
    {
        CGFloat h;
        CABasicAnimation *animation;

        h = ([self bounds].size.height - textSize.height) / 2.0;
        endFrame = NSMakeRect(0.0 - textSize.width, h, 
                              textSize.width, 
                              textSize.height);
        endPosition.x = -textSize.width / 2.0;
        endPosition.y = [self bounds].size.height / 2.0;

        animation = [CABasicAnimation animationWithKeyPath:@"position"];
        [animation setFromValue:
         [NSValue valueWithPoint:startPosititon]];
        [animation setToValue:
         [NSValue valueWithPoint:endPosition]];
        [animation setDelegate:self];
        [animation setDuration:
         [self intervalWithWidth:textSize.width speed:SLIDE_SPEED]];
        [animation setTimingFunction:
         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];

        [_textLayer addAnimation:animation forKey:@"slide"];

        //p[_textLayer setFrame:NSRectToCGRect(endFrame)];
        [_textLayer setPosition:NSPointToCGPoint(endPosition)];
    }

    [_rootLayer addSublayer:_textLayer];
}

- (NSTimeInterval)intervalWithWidth:(CGFloat)w speed:(CGFloat)s {
    return (NSTimeInterval)(w / s);
}
@end
#import "AppStatusItemView.h"

#define DEFAULT_FRAME (NSMakeRect(0 , 0 , 140 , 20))
#define SLIDE_SPEED (30.0) /* points per second */

/* ============================================================================
 MARK: -
 MARK: Private Interface
 =========================================================================== */
@interface AppStatusItemView (Private)
- (void)slide;
- (NSTimeInterval)intervalWithWidth:(CGFloat)w speed:(CGFloat)s;
@end

/* ============================================================================
 MARK: -
 MARK: Public Implementation
 =========================================================================== */
@implementation AppStatusItemView
/* MARK: Init */
- (id)initWithText:(NSString *)pS {
    self = [self initWithFrame:DEFAULT_FRAME];
    if(self != nil) {
        _text = [pS retain];

        /* Create root layer */
        {
            //CGColorRef myColor = CGColorCreateGenericRGB(0.5 , 0.0 , 0.0 , 0.5);
            _rootLayer = [[CAScrollLayer layer] retain];
            [_rootLayer setFrame:NSRectToCGRect([self bounds])];
            //[_rootLayer setBackgroundColor:myColor];
            [self setWantsLayer:YES];
            [self setLayer:_rootLayer];
            //CGColorRelease(myColor);
        }

        /* Create text layer */
        {
            CGColorRef myColor = CGColorCreateGenericRGB(0.0 , 0.0 , 0.0 , 1.0);
            _textLayer = [[CATextLayer layer] retain];
            [_textLayer setFontSize:12.0];
            [_textLayer setForegroundColor:myColor];
            [self slide];
            CGColorRelease(myColor);
        }

    }
    return self;
}

- (void)dealloc {
    [_text release];
    [_textLayer release];
    [_rootLayer release];
    [super dealloc];
}

/* MARK: Properties */ 
@synthesize text=_text;
- (void)setText:(NSString *)pT {
    if(![_text isEqualToString:pT]) {
        [_text release];
        _text = [pT retain];
    }
}

/* MARK: Animation Delegate */
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    if(flag) {
        [self slide];
    }
}
@end

/* ============================================================================
 MARK: -
 MARK: Private Implementation
 =========================================================================== */
@implementation AppStatusItemView (Private)
- (void)slide {
    NSRect startFrame, endFrame;
    NSPoint startPosititon, endPosition;
    NSSize textSize;

    [_textLayer removeFromSuperlayer];

    /* Set start frame and position */
    {
        NSDictionary *attributes;
        NSFont *font;
        CGFloat h;

        font = [NSFont fontWithName:@"Helvetica" 
                               size:12.0];
        attributes = [NSDictionary dictionaryWithObject:font 
                                                 forKey:NSFontAttributeName];
        textSize = [_text sizeWithAttributes:attributes];

        h = ([self bounds].size.height - textSize.height) / 2.0;
        startFrame = NSMakeRect([self bounds].size.width,
                                h, textSize.width , textSize.height);
        startPosititon.x = [self bounds].size.width + textSize.width / 2.0;
        startPosititon.y = [self bounds].size.height / 2.0;

        [_textLayer setString:_text];
        [_textLayer setFrame:NSRectToCGRect(startFrame)];
        [_textLayer setPosition:NSPointToCGPoint(startPosititon)];
    }

    /* Slide to end position */
    {
        CGFloat h;
        CABasicAnimation *animation;

        h = ([self bounds].size.height - textSize.height) / 2.0;
        endFrame = NSMakeRect(0.0 - textSize.width, h, 
                              textSize.width, 
                              textSize.height);
        endPosition.x = -textSize.width / 2.0;
        endPosition.y = [self bounds].size.height / 2.0;

        animation = [CABasicAnimation animationWithKeyPath:@"position"];
        [animation setFromValue:
         [NSValue valueWithPoint:startPosititon]];
        [animation setToValue:
         [NSValue valueWithPoint:endPosition]];
        [animation setDelegate:self];
        [animation setDuration:
         [self intervalWithWidth:textSize.width speed:SLIDE_SPEED]];
        [animation setTimingFunction:
         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];

        [_textLayer addAnimation:animation forKey:@"slide"];

        //p[_textLayer setFrame:NSRectToCGRect(endFrame)];
        [_textLayer setPosition:NSPointToCGPoint(endPosition)];
    }

    [_rootLayer addSublayer:_textLayer];
}

- (NSTimeInterval)intervalWithWidth:(CGFloat)w speed:(CGFloat)s {
    return (NSTimeInterval)(w / s);
}
@end