0

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

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

我应该怎么做才能做到这一点?

4

2 回答 2

3

这种事情真是太麻烦了,而且(据我所知)没有简单的现有方法。

首先,您必须通过使每个块的长度相同来简化 KISS。这是如何做到的..

(1) 为每个“块”制作一个标准宽度(例如 100 像素)。

这些块只是 UIViews(或者可能只是文本标签)。您对动态创建 UIView 感到满意吗?如果没有,我们会告诉你怎么做!

(2) 选择一个完全离开屏幕的旅程的起点

(3) 选择一个完全离开屏幕左侧的旅程终点

(3b) 选择您想要的从 point1 到 point2 的确切时间(比如“4.71937s”)

(4) 精确计算(精确到精确!)块从右到左移动其自身长度所需的秒数。假设 0.91763 秒

您必须使用 NSTimers 来执行此操作。你对他们熟悉吗?

(5) 设置一个重复的 0.91763 秒计时器,它:创建一个新块,
(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 点没有改变。)

希望能帮助到你!

于 2010-12-23T07:31:06.140 回答
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
于 2010-12-28T00:11:13.343 回答