循环UIScrollView,但继续减速
我build立了一个无限的滚动视图,当它达到0的内容偏移量时,我将它设置为最大内容偏移量,反之亦然。
即
[scrollView setContentOffset:CGPointMake(0,0) animated:NO];
这工作,但它停止UIScrollView减速。
有没有办法做到这一点,但保持UIScrollView减速?
我试过这个…
float declerationRate = scrollView.decelerationRate; [scrollView setContentOffset:CGPointMake(scrollView.frame.size.width, 0) animated:NO]; scrollView.decelerationRate = declerationRate;
但它没有工作。
编辑
我刚刚意识到,减速度是决定减速度如何慢/快的设置。
我需要的是从scrollView获取当前的速度。
对,我不得不稍微调整一下这个想法。
试图设置一个UIScrollView的速度是困难的…非常困难。
所以无论如何,我调整了它。
在回答别人的问题之后,这实际上是一个小型项目,我想我会自己去解决这个问题。
我想创build一个微调应用程序,我可以刷卡旋转箭头,所以它旋转和减速到一个点。
我所做的是build立一个UIImageView箭头指向。
然后覆盖UIImageView是一个UIScrollView。
然后在代码中
@interface MyViewController () <UIScrollViewDelegate> @property (nonatomic, weak) IBOutlet UIScrollView *scrollView; @property (nonatomic, weak) IBOutlet UIImageView *arrowView; @end @implementation MyViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //make the content size really big so that the targetOffset of the deceleration will never be met. self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 100, self.scrollView.frame.size.height); //set the contentOffset of the scroll view to a point in the center of the contentSize. [self.scrollView setContentOffset:CGPointMake(self.scrollView.frame.size.width * 50, 0) animated:NO]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)rotateImageView { //Calculate the percentage of one "frame" that is the current offset. // each percentage of a "frame" equates to a percentage of 2 PI Rads to rotate float minOffset = self.scrollView.frame.size.width * 50; float maxOffset = self.scrollView.frame.size.width * 51; float offsetDiff = maxOffset - minOffset; float currentOffset = self.scrollView.contentOffset.x - minOffset; float percentage = currentOffset / offsetDiff; self.arrowView.transform = CGAffineTransformMakeRotation(M_PI * 2 * percentage); } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { //the scrollView moved so update the rotation of the image [self rotateImageView]; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { //the scrollview stopped moving. //set the content offset back to be in the middle //but make sure to keep the percentage (used above) the same //this ensures the arrow is pointing in the same direction as it ended decelerating float diffOffset = scrollView.contentOffset.x; while (diffOffset >= scrollView.frame.size.width) { diffOffset -= scrollView.frame.size.width; } [scrollView setContentOffset:CGPointMake(scrollView.frame.size.width * 50 + diffOffset, 0) animated:NO]; } @end
这给了一个像“幸运之轮”这样的旋转者所期望的效果,它将在任何一个方向上无休止地旋转。
虽然有一个缺陷。 如果用户继续旋转并旋转而不停止旋转,那么在停止之前,只能向任一方向旋转50圈。
正如我在评论中所说的那样,你正在做的是产生一个预期的结果,一种做你想做的方法是把内容偏移设置在最上面,但是通过使用内容大小高度和减速度值,你可以生成animation内容再次偏移,查看这个答案: https : //stackoverflow.com/a/6086521/662605
你将不得不玩一些math之前,它感觉不错,但我认为这是一个合理的解决方法。
减速度越低,animation(时间)越长,animation(距离)越长。 让我知道你的想法。
正如你所说,减速可能不是你唯一需要的。 所以你可以尝试一下contentOffset上的KVO来计算半秒内的平均速度,也许可以得到一个速度的概念。
可能有几种不同的方法来做到这一点。 理想情况下,您不必进行任何types的计算来模拟剩余的减速物理,或者使用UIScrollView
的内部UIScrollView
来进行UIScrollView
。 这很容易出错,而且不可能完美匹配每个人都习惯的UIScrollView
物理。
相反,如果你的滚动视图只是一个手势的驱动(也就是说,你实际上不需要显示任何内容),我认为最好是只有一个巨大的滚动视图。 将其初始内容偏移量设置为其内容大小的中心。 在scrollViewDidScroll(_:)
,计算遍历的屏幕宽度的百分比:
let pageWidth = scrollView.frame.width let percentage = (scrollView.contentOffset.x % pageWidth) / pageWidth
这将基本上从0.0
到1.0
(向右移动)或从1.0
到0.0
(向左移动)一遍又一遍地循环。 您可以将这些规范化的值转发给其他可以响应的函数,也许可以驱动animation。 只要构build任何代码响应这个,使得它从0.0
跳到1.0
或从1.0
跳到0.0
时看起来是无缝的。
当然,如果你需要循环发生比正常滚动视图速度更快或更慢的事情,只需使用更小或更大的屏幕宽度。 我只是随便挑选的。
如果您担心触及可滚动内容的边缘,那么当滚动视图到达完整的rest1时 ,将其内容偏移重置为相同的初始中心值,再加上任何屏幕宽度的剩余部分(或任何您使用)滚动视图是在它停止滚动时。
考虑到上面的重置方法,即使对于托pipe可见内容的滚动视图,只要更新视图帧/模型值以考虑重置滚动偏移量,就可以有效地实现无限滚动视图。
1要正确地捕获这个,实现scrollViewDidEndDecelerating(_:)
和scrollViewDidEndDragging(_:willDecelerate:)
,只有在willDecelerate
为false
情况下调用“complete rest”函数。 总是在前一种情况下调用它。
我发现,如果你打电话
[scrollView setContentOffset:CGPointMake(0,0) animated:NO];
在(0,0)点,它会触发UIScrollView的反弹动作,然后减速停止。 当您调用setContentOffset
绑定内容时,会发生同样的情况。
所以你可以调用setContentOffset
指向(10,10)或其他地方,以便轻松减速。