Как создать горизонтальный скроллер (Stock Ticker) в iPhone SDK?

Я работаю над приложением для iPhone, которое связано с фондовым рынком.

Существует требование создать горизонтальный скроллер, похожий на биржевую.

Что я должен сделать, чтобы достичь этого?

2 ответа

Решение

Такого рода вещи - чертовски неприятно, и (насколько я знаю) не существует простого способа существования.

Сначала вы должны упростить ПОЦЕЛУЙ, сделав каждый блок одинаковой длины. Вот как это сделать..

(1) сделать стандартную ширину (скажем, 100 пикселей) для каждого "блока".

Блоки будут просто UIViews (или, возможно, просто текстовые метки). Вам удобно создавать UIViews на лету? Если нет, мы расскажем вам, как это сделать!

(2) выберите начальную точку для путешествия, которое находится полностью справа от экрана

(3) выберите конечную точку для поездки, которая находится полностью слева от экрана

(3b) выберите точное время (скажем, "4.71937s"), которое вы хотите для времени в пути от точки 1 до точки 2

(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 не изменились.)

Надеюсь, поможет!

Если я правильно понимаю вопрос, то одно простое решение - просто обновить UILabel с помощью NSTimer (см. Ниже быстрый код, приведенный ниже). Для некоторых приложений этого может быть достаточно, но если вам нужно постоянно обновлять строку свежими данными, вам нужно будет проделать дополнительную работу, например, чтобы новая строка добавлялась "за кадром" как бы.

Это простое решение не дает вам особенно плавной прокрутки. Скорее он скачет на одну ширину символа за раз, и с системным шрифтом по умолчанию не каждый символ будет шире, чем любой другой.

Чтобы сделать более плавную прокрутку, вы можете визуализировать строку в графическом контексте (используйте drawInRect:withFont: on NSString), создать 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
Другие вопросы по тегам