如何在iPhone SDK中创建水平滚动条(股票行情指示器)?

发布于 2024-10-09 08:53:05 字数 91 浏览 3 评论 0原文

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

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

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

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

There is a requirement to create a horizontal scroller which is similar to a stock ticker.

What should I do to achieve that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心凉怎暖 2024-10-16 08:53:05

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

首先,您必须通过使每个块的长度相同来简化 KISS。操作方法如下:

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

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

(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 点没有改变。)

希望它有帮助!

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!

待"谢繁草 2024-10-16 08:53:05

如果我正确地理解了这个问题,那么一个简单的解决方案就是使用 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文