UITableView以一定的速度滚动?

时间:2010-10-20 14:46:31

标签: iphone xcode ipad uitableview

我正在构建一个自定义老虎机,其中包含一个uitableview列。

当用户拉动杠杆时,tableview应滚动到具有索引的特定位置。 我使用了这个方法:

- scrollToRowAtIndexPath:atScrollPosition:animated:

但是这个方法会使表格以恒定的持续时间滚动。所以你不会真正认识到长期或短期的旋转。

我正在寻找一种方法: A)减慢滚动动画。要么, B)将滚动动画的持续时间更改为自定义值。

正常的滚动动画(用手指)确实显示了这种效果。 也许这是一个愚蠢的想法,但是在我的tableView上调用touchesBegan和touchesDidEnd方法是一个想法吗?

非常感谢

8 个答案:

答案 0 :(得分:17)

可能需要朝那个方向看?

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

仅使用动画制作:否。

答案 1 :(得分:13)

因为UITableView继承自UIScrollView,所以您也可以使用setContentOffset:animated: 通过这种方式,您可以使您的桌面视图将您选择的一定数量的像素“滚动”到您喜欢的任何一侧。

这可以与scrollToRowAtIndexPath相同:atScrollPosition:animated:

我做了一个原型,只是为了告诉你它是如何工作的。

因为这是通过计时器和东西来完成的,你可以设置autoScroll将持续多长时间以及动画的速度(以及你使用contentoffset的距离)。

这是.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

如果您有任何问题可以随时发表评论,我会详细说明。

答案 2 :(得分:3)

如果您需要iOS 5,则可以使用UIScrollViewDelegate方法scrollViewWillEndDragging:withVelocity:targetContentOffset:。 这使您可以查看用户移动手指的速度,减速动画以默认速度结束的位置,并允许您覆盖动画速度,以便在不同的点结束。

答案 3 :(得分:1)

使用UIPickerView创建应用程序插槽机器的常用方法也许您应该检查一下..

答案 4 :(得分: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];
}
}

答案 5 :(得分:1)

我一直在使用Sparrow framework's补间功能来制作类似的动画。

上面的链接有一个如何设置它的示例。您可以为任何Objective C对象的任何数字属性设置动画,并且可以使用“easy in”,“ease out”,“easy in elastic”等转换,或者只是使用旧的线性动画。

属性 contentSize 虽然是 CGPoint ,但您需要在其中一个类上实际设置不同属性的动画,然后为属性设置器函数实现实际方法这样它就会更新contentOffset。

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

答案 6 :(得分: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.

注意:如果您更改了CALayers或Views的框架(例如,您可能已经添加到tableViewCell的contentView中的customView),那么这些动画将在这里开始打扰您。对于大型动画持续时间,它们将非常明显,您可能会看到奇怪的细胞行为。

在这种情况下,无论你在哪里改变你的帧等等,都要看看:

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

找到上述解决方案here

您可能还必须为图层设置操作字典,以便为所有操作返回空值。

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

这似乎为时已晚,但对于遇到同样问题的人,我希望这个答案会有所帮助。如果我犯了一些明显的(或没那么多)错误,请随时指导我。

编辑:哎呀,我看到上面答案的确切内容:( 无论如何,这个更详细,我只是一个初学者:)

答案 7 :(得分:0)

你不能(据我所知,我一直在寻找一种方法来做到这一点)制造一个不恒定的速度

- scrollToRowAtIndexPath:atScrollPosition:animated:

所以我建议......如果你真的需要它,用一些动画或其他东西制作你自己的东西,或做一些比较容易的东西可以节省你一些时间,使用UIPickerView