views:

243

answers:

2

Hi, I'm looking for some guidance on the best way to implement stock ticker style right-to-left scrolling of CALayers in Core Animation on OSX. I'm pretty new to Cocoa and don't know the best way to implement this.

I have a continuous stream of news items and stock details that I turn into CALayers (made up of 1 image and a CATextLayer) and I want to animate the CALayers from right to left of my custom view.

The news and stock information is constantly updating so I would like to add 1 item at a time to the view, scroll it right to left until the right-most point of the CALayer is showing, then add another CALayer to the view and start scrolling that as well. I would like to do this dynamic updating instead of taking a big snapshot of all my data, turning it into a big horizontal CALayer and scrolling that.

I'm looking for guidance on how to achieve this sort of effect -

do I manually animate each new CALayer along a path in the view? Or should I be using CAScrollLayer to achieve this effect?

Many thanks Glen.

+1  A: 

I'd do this with Quartz Composer and put a QCView in your app. It's a lot less work than you imagine.

NSResponder
A: 

You perhaps don't need to customize anything to do this. Here self is an object of class extending UIScrollView and with a UILabel to display the text.

////
//Header

#import <UIKit/UIKit.h>


@interface TickerScrollView : UIScrollView {

 UILabel *textLabel;

}

- (void)displayText:(NSString *)string;
- (void)clearTicker;

@property (nonatomic, retain, readwrite) UILabel *textLabel;

@end

//////
//Implementation

@implementation TickerScrollView


- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {

  // Initialization code
  [self setFrame: frame];

  [self setBounces: NO];

  [self setShowsVerticalScrollIndicator:NO];
  [self setShowsHorizontalScrollIndicator:NO];

  [self setBackgroundColor:[UIColor greenColor]];

  [self initialiseTextLabel];

    }

    return self;

}

- (void)initialiseTextLabel {

 textLabel = [[UILabel alloc] initWithFrame:self.bounds];
 [textLabel setTextAlignment:UITextAlignmentLeft];
 [textLabel setNumberOfLines:1];
 [textLabel sizeToFit];

 [self addSubview:textLabel];

 [self setScrollEnabled:YES];

}

- (void)displayText:(NSString *)string {

 [self clearTicker];

 [textLabel setText:string];
 [textLabel sizeToFit];

 [self beginAnimation];

}

- (void)clearTicker {

 [textLabel setText:@""];
 [textLabel sizeToFit];

 CGPoint origin = CGPointMake(0, 0);
 [self setContentOffset:origin];

}

- (void)beginAnimation {

 CGFloat text_width = textLabel.frame.size.width;
 CGFloat display_width = self.frame.size.width;

 if ( text_width > display_width ) {

  CGPoint origin = CGPointMake(0, 0);
  [self setContentOffset:origin];

  CGPoint terminal_origin = CGPointMake(textLabel.frame.size.width - self.frame.size.width, textLabel.frame.origin.y);
  float duration = (text_width - display_width)/40;

  [UIView beginAnimations:nil context:NULL];

  [UIView setAnimationCurve:UIViewAnimationCurveLinear];
  [UIView setAnimationDelay:1.0];
  [UIView setAnimationDuration:duration];

  [self setContentOffset:terminal_origin];

  [UIView commitAnimations];

 }

}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (void)dealloc {
    [textLabel release];
    [super dealloc];
}


@end
SpecialK