Как создать горизонтальный скроллер (Stock Ticker) в iPhone SDK? - PullRequest
0 голосов
/ 23 декабря 2010

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

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

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

Ответы [ 2 ]

3 голосов
/ 23 декабря 2010

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

Сначала вы должны упростить К.И.С.С. сделав каждый блок одинаковой длины. Вот как это сделать ..

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

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

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

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

(3b) выберите точное время (скажем, «4,71937 с»), которое вы хотите для времени в пути от точки 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 не изменились.)

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

0 голосов
/ 28 декабря 2010

Если я правильно понимаю вопрос, то одно простое решение - просто обновить 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
...