如何在iPhone SDK中创建水平卷轴(股票行情)?

时间:2010-12-23 06:39:53

标签: iphone objective-c cocoa-touch ios4 ticker

我正在开发一款与股票市场相关的iPhone应用程序。

需要创建一个类似于股票代码的水平滚动条。

我该怎么做才能实现这一目标?

2 个答案:

答案 0 :(得分:3)

这种事情是一种该死的麻烦(据我所知),现有的方法并不容易。

首先,你必须简化K.I.S.S.通过使每个块长度相同。这是怎么做的..

(1)为每个“块”制作标准宽度(例如,100 px)。

这些块只是UIViews(或者只是文本标签)。你是否习惯于在飞行中创建UIViews?如果没有,我们会告诉你如何做到这一点!

(2)选择一个完全在屏幕右侧的旅程的起点

(3)选择一个完全离开左边的旅程的终点​​

(3b)从点1到点2选择您想要的旅行时间的确切时间(比如说“4.71937s”)

(4)准确地(准确地说是!)确定块从右到左行进 它自己的长度 所需的秒数。让我们说0.91763秒

您必须使用NSTimers才能执行此操作。你熟悉它们吗?

(5)设置一个定期的0.91763s计时器,其中:创建一个新的块和
(5b)剔除下一条(如果有的话)文本信息(例如“AAPL 408.50”)和
(5c)将其放在起点2和
(5d)简单地使用核心动画开始向终点3和
动画 (5e)为这个区块启动一个单独的一次性计时器,这将在3b中提到的总时间之后销毁这个区块

就是这样。

你必须为文本项目设置一个简单的FIFO堆栈(无论你选择什么),当你从任何来源获取它们时,将它们推入它。

您是否习惯设置某种数组作为信息堆栈使用?如果不是,我们可以提供帮助! :)

请注意,在(5b)中,您可能会将刚刚使用的那个推回到堆栈的另一端,这样它们就会永远保持下去。您很可能必须能够触摸单个项目才能删除它们,或者,例如,修改价格或任何新信息的来源。

一旦你开始工作(“标准块长度方法”)。您可能更喜欢以某种方式确定每个文本块的确切长度(AAPL 400.50比AAPL 30更长)......这样做......

为每个块计算一个新的自身长度时间值(如第4点所示)。即,在第5.b.2点这样做。而不是使用循环计时器(在第5点),启动一个新的计时器(在5f)以启动下一个块。 (需要明确的是,第3b和第5e点没有变化。)

希望它有所帮助!

答案 1 :(得分:0)

如果我理解这个问题,那么一个简单的解决方案就是使用NSTimer更新UILabel(请参阅下面的快速敲击代码)。对于某些应用程序,这可能就足够了,但是如果您需要使用新数据更新字符串,那么您需要做更多的工作,例如所以新字符串就像是在屏幕外附加。

这个简单的解决方案并不能让您获得特别流畅的滚动。相反,它一次跳转一个字符宽度,并且使用默认系统字体,并非每个字符都像其他字符一样宽。

要进行更流畅的滚动,您可以将字符串渲染到图形上下文中(在NSString上使用drawInRect:withFont:),制作UIImage,然后一次微调n个像素。当您接近图像的右边缘时,您需要在第一个副本的末尾右侧第二次渲染图像。

这是简单的代码(结合了.h和.m文件),演示了粗略的方法:

//  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