xcode UITableView 以一定的速度平滑滚动?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3979119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UITableView scroll smooth with certain speed?
提问by Mats Stijlaart
I'm building a custom slot machine with a column that exists of a uitableview.
我正在构建一个带有 uitableview 列的自定义老虎机。
When the user pulls a lever the tableview should scroll to a certain position with an index. I used the method:
当用户拉动杠杆时,tableview 应该使用索引滚动到某个位置。我用的方法:
- 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.
我正在寻找一种方法: A) 减慢滚动动画。或者,B) 将滚动动画的持续时间更改为自定义值。
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?
正常的滚动动画(用手指)确实显示了这种效果。也许这是一个愚蠢的想法,但是在我的 tableView 上调用 touchesBegan 和 touchesDidEnd 方法是否是一个想法?
Thanks already
已经谢谢了
采纳答案by Totumus Maximus
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.
因为 UITableView 继承自 UIScrollView 你也可以使用 setContentOffset:animated: 这样你可以让你的 tableview “滚动”你选择的一定数量的像素到你喜欢的任何一侧。
This can be done the same with the scrollToRowAtIndexPath:atScrollPosition:animated:
这可以通过 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.
因为这是通过计时器和东西完成的,您可以设置 autoScroll 持续多长时间以及动画将持续多快(如果您使用 contentoffset 则多远)。
This is the .h file:
这是 .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
This is the .m file:
这是 .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
If you have any question feel free to leave a comment and I will elaborate.
如果您有任何问题,请随时发表评论,我会详细说明。
回答by Rubycon
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.
仅适用于动画:NO。
回答by omz
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.
如果你需要 iOS 5,你可以使用UIScrollViewDelegate
方法scrollViewWillEndDragging:withVelocity:targetContentOffset:
。这使您可以查看用户移动手指的速度、减速动画将以默认速度结束的位置,并允许您覆盖动画速度,使其在不同的点结束。
回答by Dor Bashan
the common way to make apps-slot-machines is with UIPickerView maybe you should check this..
制作应用程序老虎机的常用方法是使用 UIPickerView 也许你应该检查一下..
回答by Allen
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];
}
}
回答by MindJuice
I've been using the Sparrow framework'stweening features to do similar animations.
我一直在使用Sparrow 框架的补间功能来制作类似的动画。
The link above has an example of how to set it up. You can animate any numeric property of any Objective C object, and you can use transitions like "easy in", "ease out", "ease in elastic", etc., or just good old linear animations.
上面的链接有一个如何设置它的例子。您可以为任何 Objective C 对象的任何数字属性设置动画,并且您可以使用“easy in”、“ease out”、“ease in elastic”等过渡,或者只是很好的旧线性动画。
The property contentSizeis a CGPointthough, so you would need actually animate a different property on one of your classes and then implement an actual method for the property setter function so that it updates the contentOffset.
但是,属性contentSize是一个CGPoint,因此您实际上需要在您的一个类上为不同的属性设置动画,然后为属性设置器函数实现一个实际方法,以便它更新 contentOffset。
- (void) setTableScrollPosition:(CGFloat)position
{
CGPoint newOffset = CGPointMake(0.0, position);
scrollView.contentOffset = newOffset;
}
回答by JohnVanDijk
I searched a lot for this answer but ultimately had to come up with one of my own. You can call the method scrollAutomatically with the starting row number like:
我为这个答案搜索了很多,但最终不得不想出一个我自己的答案。您可以使用起始行号调用 scrollAutomatically 方法,例如:
[self scrollAutomatically:0];
So this is what the function looked like. I was dealing with a table which always had 3000 rows and I intended to scroll to the bottom.
所以这就是函数的样子。我正在处理一个总是有 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.
}
}];
}
Now coming to the speed of the scroll.
现在来到滚动的速度。
FOR REALLY FAST SCROLLS:
真正快速滚动:
If I set value by which I increment the row index (j) on each call of the function to 10,
i.e. if I write j = j+10;
then my 3000 rows took about 9 seconds to scroll. (3000 * mean FPS that I could muster).
If I set it to j = j+20;
then the 3000 rows took about 4.5 seconds. So you get the idea.
To make it scroll slower reduce the increment value.
如果我将每次调用函数时将行索引 (j) 增加到 10 的值设置为值,即如果我写入,j = j+10;
那么我的 3000 行滚动需要大约 9 秒。(3000 * 表示我可以召集的 FPS)。如果我将它设置为j = j+20;
那么 3000 行大约需要 4.5 秒。所以你明白了。要使其滚动更慢,请减小增量值。
FOR SLOW, READABLE SCROLLS:
对于缓慢、可读的滚动:
[UIView animateWithDuration: 1.5//this will directly set your speed. n rows scrolled every 1.5 seconds.
NOTE: If you change frames of CALayers or Views (eg. a customView you may have added to the contentView of your tableViewCell), then those animations will start to bother you here. For a large animation duration, they will be very visible and you may see strange cell beahviour.
注意:如果您更改 CALayer 或视图的框架(例如,您可能已添加到 tableViewCell 的 contentView 的自定义视图),那么这些动画将在这里开始打扰您。对于较长的动画持续时间,它们将非常明显,您可能会看到奇怪的细胞行为。
In that case wherever you change your frames etc. look at something like:
在这种情况下,无论您在哪里更改框架等,请查看以下内容:
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
[myView.myCALayer.frame = (CGRect){ { 10, 10 }, { 100, 100 } ];
[CATransaction commit];
Find the above solution here.
在此处找到上述解决方案。
You may also have to set the actions dictionary for the layer to return nulls for all actions.
您可能还必须为图层设置动作字典,以便为所有动作返回空值。
NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"sublayers", nil];
superlayer.actions = newActions;
This seems to be too late but for people facing the same problem I hope this answer will be helpful. Also please feel free to guide me in case I have made some obvious (or not so much) blunder.
这似乎为时已晚,但对于面临同样问题的人,我希望这个答案会有所帮助。另外请随时指导我,以防我犯了一些明显(或不那么严重)的错误。
Edit: Oops, I see the exact thing above my answer :( Anyways, this is a bit more detailed and I am only a beginner :)
编辑:糟糕,我在我的答案上方看到了确切的内容:(无论如何,这更详细一点,我只是一个初学者:)
回答by Gabriel
You can't (to my knowledge, I have been looking everywhere for a way to do this) make a speed that isn't constant for
你不能(据我所知,我一直在寻找一种方法来做到这一点)使速度不是恒定的
- scrollToRowAtIndexPath:atScrollPosition:animated:
So I would suggest... that if you really need it, make your own out of some animation or something, or do something alot easier that would save you some time, use UIPickerView
所以我建议......如果你真的需要它,用一些动画或其他东西制作你自己的,或者做一些更容易的事情来节省你一些时间,使用 UIPickerView