UITableView scroll smooth with certain speed?

I'm building a custom slot machine with a column that exists of a uitableview.

When the user pulls a lever the tableview should scroll to a certain position with an index. I used the method:

- scrollToRowAtIndexPath:atScrollPosition:animated:

But this method will make the table scroll with a constant duration. So you will not really recognize a long or short spin.

I'm looking for a way to: A) Slow down the scroll animation. Or, B) Change the duration for the scroll animation to a self defined value.

The normal scroll animation (with the finger) does show this effect. Maybe it is a stupid idea, but is it an idea to invoke a touchesBegan and touchesDidEnd method on my tableView?

Thanks already


May need to look in that direction?

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

Work only with animated:NO.


Because a UITableView inherits from UIScrollView you might also use setContentOffset:animated: This way you can make your tableview "scroll" a certain amount of pixels of your choosing to any side you like.

This can be done the same with the scrollToRowAtIndexPath:atScrollPosition:animated:

I made a prototype just to show you how it works.

Because this is done with timers and stuff you can set how long the autoScroll will last and how fast (and how far if you're using the contentoffset) the animation will go.

This is the .h file:

#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

This is the .m file:

#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

If you have any question feel free to leave a comment and I will elaborate.


If you can require iOS 5, you could use the UIScrollViewDelegate method scrollViewWillEndDragging:withVelocity:targetContentOffset:. This allows you to see, how fast the user was moving the finger, where the deceleration animation would end with the default speed, and it allows you to override the animation speed, so that it ends at a different point.


the common way to make apps-slot-machines is with UIPickerView maybe you should check this..


How about setup a timer and then call the scroll when timer fires:

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];
}
}