2010-10-20 3 views
18

Я создаю пользовательский игровой автомат со столбцом, который существует в uitableview.UITableView прокручивается с определенной скоростью?

Когда пользователь потянет рычаг, столбец должен прокрутить до определенной позиции с индексом. я использовал метод:

- scrollToRowAtIndexPath:atScrollPosition:animated: 

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

Я ищу способ: A) Уменьшить анимацию прокрутки. Или, B) Измените продолжительность анимации прокрутки на самоопределенное значение.

Нормальная анимация прокрутки (с помощью пальца) показывает этот эффект. Возможно, это глупая идея, но есть ли идея вызвать метод touchesBegan и touchhesDidEnd на моем столеView?

Спасибо уже

+0

ничего по этому поводу? –

ответ

12

Поскольку UITableView наследует от UIScrollView вы можете также использовать setContentOffset: анимированный: Таким образом, вы можете сделать свой TableView «прокрутите» определенное количество пикселей по вашему выбору на любую сторону, которая вам нравится.

Это можно сделать то же самое с scrollToRowAtIndexPath: atScrollPosition: анимированные:

Я сделал прототип, чтобы показать вам, как это работает.

Поскольку это делается с помощью таймеров и т. Д., Вы можете указать, как долго будет длиться autoScroll и насколько быстро (и насколько далеко вы используете контент-контент) анимация будет идти.

Это .h файл:

#import <UIKit/UIKit.h> 

@interface AutomaticTableViewScrollViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> 
{ 
    UITableView *slotMachine; 
    NSMutableArray *listOfItems; 
    NSTimer *tableTimer; 
} 

@property (nonatomic,retain) UITableView *slotmachine; 
@property (nonatomic,retain) NSMutableArray *listOfItems; 
@property (nonatomic,retain) NSTimer *tableTimer; 

-(void)automaticScroll; 
-(void)stopscroll; 

@end 

Это файл .m:

#import "AutomaticTableViewScrollViewController.h" 

@implementation AutomaticTableViewScrollViewController 

@synthesize slotmachine; 
@synthesize listOfItems; 
@synthesize tableTimer; 

-(void)loadView 
{ 
    [super loadView]; 

    slotmachine = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain]; 
    slotmachine.delegate = self; 
    slotmachine.dataSource = self; 
    [self.view addSubview:slotmachine]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{  
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    } 

    // Set up the cell... 
    if (indexPath.row % 2 == 0) 
    { 
     cell.textLabel.text = @"blalala"; 
    } 

    return cell; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return 99999; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    //you might want to do this action in ur buttonTargetMethod 
    //start timers 
    tableTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 //this value arranges the speed of the autoScroll 
                target:self 
               selector:@selector(automaticScroll) 
               userInfo:nil 
                repeats:YES]; 

    [NSTimer scheduledTimerWithTimeInterval:5 //this arranges the duration of the scroll 
            target:self 
            selector:@selector(stopscroll) 
            userInfo:nil 
            repeats:NO]; 
} 

-(void)automaticScroll 
{ 
    [slotmachine setContentOffset:CGPointMake(slotmachine.contentOffset.x, slotmachine.contentOffset.y + 50) animated:YES]; //the 50 stands for the amount of movement every tick the timer will make 
} 

-(void)stopscroll 
{ 
    //stop tabletimer again 
    [tableTimer invalidate]; 
} 

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
{ 
    return YES; 
} 

@end 

Если у вас есть какие-либо вопросы, не стесняйтесь оставить комментарий, и я остановлюсь.

15

Возможно, вам нужно посмотреть в этом направлении?

[UIView animateWithDuration: 1.0 
        animations: ^{ 
         [tableViewExercises scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:previousSelectedExerciseCell inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
        }completion: ^(BOOL finished){ 
        } 
    ]; 

Работает только с анимированными: НЕТ.

+10

Для меня это работает только тогда, когда ячейка назначения находится на экране. Когда это не так. Все ячейки, проходящие по экрану, не будут инициализированы ... У меня есть 100 ячеек. И прокрутите с первого по 80-е. Когда он запускается, каждый становится пустым, а затем 80-е и выше появляется на экране и прекращает прокрутку. –

+0

yep, это потому, что анимация работает в основном потоке точно так же, как tableViewCell-construction. Вы можете запустить анимацию в фоновом потоке, но, как вы должны знать, небезопасно выполнять операции пользовательского интерфейса в фоновом потоке. Тем не менее, он должен работать большую часть времени. (на самом деле, возможно, scrollToRowAtIndexPath: это не метод UI напрямую, но если это так, вы можете время от времени получать действительно странные ошибки, и вы не догадаетесь, откуда они пришли). – 2011-10-17 20:09:05

+5

Это работает отлично. Кроме одной маленькой проблемы дизайна. Ячейки над ячейкой у данного 'indexPath' исчезают до начала анимации. –

1

общий способ сделать APPS-слот-машины с UIPickerView может быть, вы должны проверить это ..

2

Если вам может потребоваться iOS 5, вы можете использовать метод UIScrollViewDelegatescrollViewWillEndDragging:withVelocity:targetContentOffset:. Это позволяет вам видеть, как быстро пользователь двигал пальцем, где анимация замедления заканчивается скоростью по умолчанию, и позволяет вам переопределить скорость анимации, чтобы она заканчивалась в другой точке.

0

Вы не можете (к моему знанию, я повсюду искал способ сделать это) сделать скорость, которая не является постоянной для

- scrollToRowAtIndexPath:atScrollPosition:animated: 

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

1

Как насчет настройки таймера, а затем вызовите свиток при срабатывании таймера:

start_index = 0; 
dest_index = 20; 
timer = [NSTimer scheduledTimerWithTimeInterval:(0.1) target:self selector:@selector(rolling) userInfo:nil repeats:YES];     


- (void)rolling { 
start_index++; 
if (start_index < dest_index) { 
    NSIndexPath *Index = [NSIndexPath indexPathForRow:start_index inSection:0]; 
    [self.tableView scrollToRowAtIndexPath:Index atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; 
} else { 
    [timer invalidate]; 
} 
} 
1

Я использовал функции анимации Sparrow framework's для создания аналогичных анимаций.

В приведенной выше ссылке приведен пример настройки. Вы можете анимировать любое числовое свойство любого объекта Objective C, и вы можете использовать такие переходы, как «легкость», «облегчение», «легкость в эластичности» и т. Д., Или просто хорошая старая линейная анимация.

Свойства contentSize является CGPoint хотя, так что вам нужно будет на самом деле анимировать другое свойство на одном из классов, а затем осуществить фактический метод для функции свойства сеттера так, что он обновляет contentOffset.

- (void) setTableScrollPosition:(CGFloat)position 
{ 
    CGPoint newOffset = CGPointMake(0.0, position); 
    scrollView.contentOffset = newOffset; 
} 
+0

Или вы можете просто использовать CAMediaTimingFunction, о котором я не знал до сегодняшнего дня! Doh! – MindJuice

1

Я много искал для этого ответа, но в конечном итоге должен был придумать один из моих собственных. Вы можете вызвать метод scrollAutomatically с исходным номером строки, как:

[self scrollAutomatically:0]; 

Так это то, что функция выглядит. Я имел дело с таблицей, которая всегда имела 3000 рядов, и я собирался прокручивать ее донизу.

- (void) scrollAutomatically:(int) i 
{ 
    __block int j = i; 
    [UIView animateWithDuration: 0//Change this to something more for slower scrolls 
        animations: ^{ 
         [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:j inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO]; 
        } 
        completion: ^(BOOL finished){ 
         j = j + 10;//Changing this number affects speed. 
         if(j<=2999)//here you could provide the index of destination row 
          [self scrollAutomatically:j]; 
         else 
         { 
          //I had some code here that popped up a UIAlertView. 
         } 
        }]; 
} 

Теперь, приближаясь к скорости свитка.

ДЛЯ очень быстро Свиток:

Если установить значение, на которое я увеличиваем индекс строки (J) при каждом вызове функции до 10, т.е. если я пишу j = j+10; тогда мои 3000 строк потребовались около 9 секунд прокручивать. (3000 * означает FPS, который я мог бы собрать). Если я установил его на j = j+20;, то 3000 рядов заняли около 4,5 секунд. Итак, вы поняли эту идею. Чтобы ускорить его прокрутку, уменьшите значение приращения.

ДЛЯ МЕДЛЕННО, считываемых Свиток:

[UIView animateWithDuration: 1.5//this will directly set your speed. n rows scrolled every 1.5 seconds. 

ПРИМЕЧАНИЯ: (. Например customView вы, возможно, добавили к contentView вашего tableViewCell) Если изменить кадры CALayers или Views, то эти анимации начнут беспокоить вас здесь. Для большой продолжительности анимации они будут очень заметны, и вы можете увидеть странную ячейку beahviour.

В таком случае, где бы вы изменить свои кадры и т.д. смотреть на что-то вроде:

[CATransaction begin]; 
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
[myView.myCALayer.frame = (CGRect){ { 10, 10 }, { 100, 100 } ]; 
[CATransaction commit]; 

Найти вышеуказанное решение here.

Вам также может потребоваться установить словарь действий для слоя, чтобы возвращать значения NULL для всех действий.

NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"sublayers", nil]; 
superlayer.actions = newActions; 

Это, кажется, слишком поздно, но для людей, сталкивающихся с одной и той же проблемой, я надеюсь, что этот ответ будет полезен. Также, пожалуйста, не стесняйтесь руководить мной, если я сделал несколько очевидных (или не столько) ошибок.

Edit: К сожалению, я вижу точную вещь выше мой ответ :( В любом случае, это немного более подробные и я буду только начинающий :)

Смежные вопросы