循环的UIScrollView而是继续减速(Loop UIScrollView but contin

2019-07-19 02:05发布

我已经成立了一个无限滚动视图,当它到达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;

但没有奏效。

编辑

我刚刚意识到decelerationRate是确定如何快/慢的减速设置。

我需要的是摆脱了滚动当前速度。

Answer 1:

好吧,我不得不调整思路了一下。

原来,试图建立一个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个自旋在任何一个方向。



Answer 2:

正如我在评论说,你正在做的是产生预期结果的方式,做你想做的一个办法是设置内容偏移到顶部,但然后使用内容大小的高度和减速度值,你可以动画内容再次偏移,看看这个答案: https://stackoverflow.com/a/6086521/662605

你将不得不玩弄一些数学才觉得不对劲,但我认为这是一个合理的解决方法。

减速越低,时间越长,动画(时间)和更它将动画(距离)。 让我知道你的想法。

正如你所说,减速可能不是你唯一需要的。 所以,你可以尝试在contentOffset志愿计算平均速度超过半秒可能获得速度的想法。



Answer 3:

可能有几种不同的方式来做到这一点。 理想情况下,你会不会做任何类型的计算模拟剩余减速物理或惹周围所有UIScrollView的内部。 这是容易出错,这是不太可能完全匹配UIScrollView物理学每个人的习惯。

相反,对于您的滚动视图仅仅是一种姿态(即,你实际上并不需要显示在它的任何东西),我认为这是最好的只是有一个大型宽滚动查看司机的情况。 设置初始内容偏移到它的内容大小的中心。 在scrollViewDidScroll(_:) ,计算走过屏幕宽度的百分比:

let pageWidth = scrollView.frame.width
let percentage = (scrollView.contentOffset.x % pageWidth) / pageWidth

这将基本上循环从0.01.0 (向右移动),或从1.00.0以上(向左移动)而过。 您可以将这些标准化值转发到可以响应它,也许是为了推动动画一些其他的功能。 只是结构的任何代码响应此,使得它从跳转时会出现无缝0.01.0或者从1.00.0

当然,如果你需要你的循环出现比正常滚动视图速度更快或更慢,只需要使用屏幕宽度更小或更大比例什么的。 我拿起那随意。

如果你担心击中滚动内容的边缘,那么当滚动视图来彻底休息1,重置其内容偏移到相同的初始中心值,加上无论屏幕宽度的其余部分(或任何你使用)滚动视图是在当它停止滚动。

鉴于上面的复位方法,即使你在哪里托管可见内容滚动视图,可以有效地实现无限滚动视图只要你更新的任何视图帧/模型值考虑到重置滚动偏移量。


1要正确捕捉到这些,实施scrollViewDidEndDecelerating(_:)scrollViewDidEndDragging(_:willDecelerate:) ,只要求在后一种情况下你的“彻底休息”功能时willDeceleratefalse 。 始终把它在前者的情况下。



Answer 4:

我发现,如果你打电话

[scrollView setContentOffset:CGPointMake(0,0) animated:NO];

在点(0,0),这将触发UIScrollView的反弹动作,则减速停止。 同样的情况发生在当你调用setContentOffset到绑定的内容。

所以,你可以调用setContentOffset点(10,10)或别的地方轻松地减速。



文章来源: Loop UIScrollView but continue decelerating