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