我设置了无限滚动视图,当它达到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获取当前速度。
答案 0 :(得分:2)
对,我不得不稍微调整一下这个想法。
原来试图设置UIScrollView的速度很困难......非常困难。
所以无论如何,我有点调整它。
在回答别人的问题之后,这实际上是一个迷你项目,我想我会尝试自己解决这个问题。
我想创建一个微调器应用程序,我可以滑动以旋转箭头,使其旋转并减速到一定程度。
我所做的是设置一个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次。
答案 1 :(得分:1)
正如我在评论中所说,你正在做的是产生一个预期的结果,你想要的一种方法是将内容偏移设置为顶部,然后使用内容大小的高度和减速度值,您可以再次为内容偏移设置动画,请查看以下答案:https://stackoverflow.com/a/6086521/662605
在感觉正确之前你必须要玩一些数学,但我认为这是一个合理的解决方法。
减速度越低,动画(时间)越长,动画(距离)越多。让我知道你的想法。
正如你所说,减速可能不是你唯一需要的。因此,您可以尝试在contentOffset上使用KVO来计算超过半秒的平均速度,以便了解速度。
答案 2 :(得分:0)
可能有几种不同的方法可以做到这一点。理想情况下,您不必进行任何类型的计算来模拟剩余的减速物理或使用UIScrollView
的内部结构进行混乱。它容易出错,并且不太可能完全匹配每个人过去常见的UIScrollView
物理。
相反,对于您的滚动视图仅仅是手势的驱动程序(即,您实际上不需要在其中显示任何内容)的情况,我认为最好只有一个大的宽度滚动视图。将其初始内容偏移量设置为其内容大小的中心。在scrollViewDidScroll(_:)
中,计算遍历的屏幕宽度的百分比:
let pageWidth = scrollView.frame.width
let percentage = (scrollView.contentOffset.x % pageWidth) / pageWidth
这将基本上从0.0
循环到1.0
(向右移动)或从1.0
循环到0.0
(向左移动)。您可以将这些规范化值转发给可以响应它的其他函数,也许是为了驱动动画。只需构造响应此代码的任何代码,以便在从0.0
跳到1.0
或从1.0
跳到0.0
时看起来无缝。
当然,如果您需要循环比正常滚动视图速度更快或更慢的任何循环,只需使用更小或更大的屏幕宽度部分。我只是随意挑选。
如果您担心碰到可滚动内容的边缘,那么当滚动视图达到完全休息 1 时,将其内容偏移重置为相同的初始中心值,再加上无论屏幕宽度的其余部分(或者您正在使用的任何内容),滚动视图在停止滚动时都处于显示状态。
鉴于上面的重置方法,即使对于您可以托管可见内容的滚动视图,只要更新任何视图帧/模型值以考虑重置滚动偏移,您就可以有效地实现无限滚动视图
1 要正确捕获此信息,请执行scrollViewDidEndDecelerating(_:)
和scrollViewDidEndDragging(_:willDecelerate:)
,只需拨打#34;完成休息&#34; willDecelerate
为false
时后一种情况的函数。总是在前一种情况下调用它。
答案 3 :(得分:0)
我发现如果你打电话
[scrollView setContentOffset:CGPointMake(0,0) animated:NO];
在点(0,0)处,它将触发UIScrollView的弹跳动作,然后减速将停止。当您将setContentOffset
调用到内容范围时,会发生同样的情况。
所以你可以调用setContentOffset
指向(10,10)或其他地方以轻松保持减速。