开发者

How to create a horizontal scroller (Stock Ticker) in iPhone SDK?

I am working on an iPhone app which is related to stock market.

There is a requirement to开发者_如何学Python create a horizontal scroller which is similar to a stock ticker.

What should I do to achieve that?


This sort of thing is a damn nuisance and (as far as I know) there is no easy existing way.

First you must simplify K.I.S.S. by making each block the same length. Here's how to do it..

(1) make a standard width (say, 100 px) for each "block".

The blocks would simply be UIViews (or perhaps just text labels). Are you comfortable with creating UIViews on the fly? If not we will tell you how to do it!

(2) pick a start point for the journey which is just to the right completely offscreen

(3) pick an end point for the journey which is just to the left completely offscreen

(3b) choose the exact time (say "4.71937s") you want for the travel time from point1 to point2

(4) figure out precisely (as in exactly precisely!) the seconds it takes for the block to travel it's own length from right to left. let's say 0.91763 seconds

You have to use NSTimers to do this. Are you familiar with them?

(5) set up a recurring 0.91763s timer which: makes a new block and
(5b) sucks off the next, if any, piece of text information (say "AAPL 408.50") and
(5c) places it at the start point2 and
(5d) simply using core animation begins it animating towards the end point3 and
(5e) launch an individual one shot timer for this block, which will destroy this block after the overall time mentioned in 3b

That's it.

You will have to set up a simple FIFO stack for the text items (whatever you you choose), as you get them from whatever source, shove them in to it.

Are you comfortable setting up some sort of array to use as a stack of info? Again if not we can help! :)

Note that in (5b) you would likely shove the one you just used back on the other end of the stack so they all keep going forever. It's quite likely you would have to be able to touch individual items to delete them or, eg, modify the price or whatever as new info comes in.

Once you get this working ("standard block length method"). You may prefer to somehow work out the exact length of each text block (AAPL 400.50 is longer than AAPL 30)...to do so...

Calculate on the fly a new own-length time value (as in point 4) for each block just for that block. ie, do that at point 5.b.2. instead of using a recurring timer (in point 5), fire off a new timer (at 5f) to launch the next block. (To be clear, points 3b and 5e are unchanged.)

Hope it helps!


If I understand the question aright, then one simple solution is just to update a UILabel using an NSTimer (see quickly knocked up code below). For some applications this might be enough, but if you need to keep updating the string with fresh data then you'll need to do some more work, e.g. so the new string is appending 'off screen' as it were.

This simple solution does not give you particularly smooth scrolling. Rather it jumps one character width at a time and, with the default system font, not every character is as wider as every other.

To do smoother scrolling, you could render the string into a graphics context (use drawInRect:withFont: on an NSString), make a UIImage, and then nudge that along by n pixels at a time. When you get near to the right margin of the image, you'll need to render the image a second time to the right of the end of the first copy.

Here's the simple code (with .h and .m files combined) that demonstrates the crude approach:

//  stock ticker example code
//
//  Created by Matthew Elton on 27/12/2010.
//  http://www.obliquely.org.uk/blog/app All rights reserved.
//

#define TICKER_WIDTH 250.0
#define TICKER_FONT_SIZE 18.0
#define TICKER_RATE 0.2 // nudge along five times a second

#import <UIKit/UIKit.h>

@interface tickerAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    NSString* tickerString;
    UILabel *tickerLabel;
}

@property (nonatomic, retain) NSString* tickerString;
@property (nonatomic, retain) UILabel* tickerLabel;
@property (nonatomic, retain) IBOutlet UIWindow *window;

- (void) nudgeTicker: theTimer;

@end

@implementation tickerAppDelegate

@synthesize window, tickerString, tickerLabel;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    [self setTickerString: @"This is the sample string to use on the ticker. It is quite long. So I need to fill it out with random content. "];

    CGSize labelContentSize = [[self tickerString] sizeWithFont: [UIFont systemFontOfSize:TICKER_FONT_SIZE] forWidth: 2000.0 lineBreakMode: UILineBreakModeClip];

    [self setTickerLabel: [ [ [UILabel alloc] initWithFrame:CGRectMake(20,40,TICKER_WIDTH, labelContentSize.height)] autorelease]];

    [[self tickerLabel] setFont: [UIFont systemFontOfSize:TICKER_FONT_SIZE]];
    [[self tickerLabel] setText: [self tickerString]];
    [[self tickerLabel] setBackgroundColor:[UIColor lightGrayColor]];
    [[self tickerLabel] setLineBreakMode:UILineBreakModeClip];
    [NSTimer scheduledTimerWithTimeInterval:TICKER_RATE target:self selector: @selector(nudgeTicker:) userInfo:nil repeats:YES];

    [window addSubview:[self tickerLabel]];
    [self.window makeKeyAndVisible];

    return YES;
}


- (void) nudgeTicker: theTimer;
{
    NSString* firstLetter = [[self tickerString] substringWithRange: NSMakeRange(0,1)];
    NSString* remainder = [[self tickerString] substringWithRange:NSMakeRange(1,[[self tickerString] length]-1)];
    [self setTickerString:  [remainder stringByAppendingString: firstLetter]];
    [[self tickerLabel] setText:[self tickerString]];
}


- (void)dealloc {
    [window release];
    [tickerString release];
    [tickerLabel release];
    [super dealloc];
}

@end
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜