我正在尝试使用CATextLayer在视图中滑动文本,但它显然不起作用:
函数animationDidStop:finished:
被调用一次,但NO为flag
值。
代码(NSView子类):
#import "AppStatusItemView.h"
#define DEFAULT_FRAME (NSMakeRect(0 , 0 , 80 , 20))
/* ============================================================================
MARK: -
MARK: Private Interface
=========================================================================== */
@interface AppStatusItemView (Private)
- (void)updateLayer;
- (CATextLayer *)makeTextLayer;
- (CABasicAnimation *)makeMoveAnimation;
@end
/* ============================================================================
MARK: -
MARK: Public Implementation
=========================================================================== */
@implementation AppStatusItemView
/* MARK: Init */
- (id)initWithText:(NSString *)pS {
self = [self initWithFrame:DEFAULT_FRAME];
if(self != nil) {
_text = [pS retain];
/* initialize view */
[self updateLayer];
}
return self;
}
- (void)dealloc {
[_text release];
[_textLayer release];
[super dealloc];
}
/* MARK: Properties */
@synthesize text=_text;
- (void)setText:(NSString *)pT {
if(![_text isEqualToString:pT]) {
[_text release];
_text = [pT retain];
[self updateLayer];
}
}
/* MARK: Animation Delegate */
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
if(flag) {
CABasicAnimation *myAnimation;
myAnimation = [self makeMoveAnimation];
[myAnimation setDelegate:self];
[_textLayer addAnimation:myAnimation forKey:@"slide"];
}
}
@end
/* ============================================================================
MARK: -
MARK: Private Implementation
=========================================================================== */
@implementation AppStatusItemView (Private)
- (void)updateLayer {
CABasicAnimation *myAnimation;
CATextLayer *myLayer;
myLayer = [self makeTextLayer];
myAnimation = [self makeMoveAnimation];
[_textLayer removeAllAnimations];
[_textLayer removeFromSuperlayer];
[_textLayer release];
_textLayer = [myLayer retain];
[[self layer] addSublayer:_textLayer];
[myAnimation setDelegate:self];
[_textLayer addAnimation:myAnimation forKey:@"slide"];
}
- (CATextLayer *)makeTextLayer {
CATextLayer *layer;
NSString *myString;
CGRect myFrame;
CGPoint myPosition;
myString = _text;
layer = [[CATextLayer layer] retain];
[layer setString:myString];
myFrame.origin = CGPointZero;
myFrame.size = NSSizeToCGSize([myString sizeWithAttributes:nil]);
[layer setFrame:myFrame];
myPosition.y = 1.0;
myPosition.x = [self bounds].size.width + 2.0;
[layer setPosition:myPosition];
return [layer autorelease];
}
- (CABasicAnimation *)makeMoveAnimation {
CABasicAnimation *animation;
CGPoint myPoint;
myPoint.y = 1.0;
animation = [CABasicAnimation animationWithKeyPath:@"position"];
myPoint.x = [self bounds].size.width + 1.0;
[animation setFromValue:[NSValue valueWithPoint:myPoint]];
myPoint.x = -[_textLayer bounds].size.width - 1.0;
[animation setToValue:[NSValue valueWithPoint:myPoint]];
[animation setTimingFunction:
[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setDuration:5.0];
return animation;
}
@end
提前谢谢你,
ief2
答案 0 :(得分:0)
我已经更改了代码,但没有调试以前的代码。
新实施,如果有人想看到它:
#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