Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa touch UIScrollView-减速时捕捉控制_Cocoa Touch_Ios_Uiscrollview - Fatal编程技术网

Cocoa touch UIScrollView-减速时捕捉控制

Cocoa touch UIScrollView-减速时捕捉控制,cocoa-touch,ios,uiscrollview,Cocoa Touch,Ios,Uiscrollview,有很多信息可供程序员使用,但我看不到一个明显的方法来控制从滚动手势减速后控件停止的位置 基本上,我希望scrollview捕捉到屏幕的特定区域。用户仍然可以像正常情况一样滚动,但是当他们停止滚动时,视图应该捕捉到最相关的位置,如果是轻弹手势,减速也应该在这些位置停止 有没有一种简单的方法来做这样的事情,或者我应该考虑唯一的方法来实现一个自定义的滚动控件吗?< /p> 在 ScReVIEW DestDeloDest:: >代码> ScReVIEW DeDigDractRoo: WeldHelt::

有很多信息可供程序员使用,但我看不到一个明显的方法来控制从滚动手势减速后控件停止的位置

基本上,我希望scrollview捕捉到屏幕的特定区域。用户仍然可以像正常情况一样滚动,但是当他们停止滚动时,视图应该捕捉到最相关的位置,如果是轻弹手势,减速也应该在这些位置停止


有没有一种简单的方法来做这样的事情,或者我应该考虑唯一的方法来实现一个自定义的滚动控件吗?< /p> 在<代码> ScReVIEW DestDeloDest::<代码> >代码> ScReVIEW DeDigDractRoo: WeldHelt::/Cuth>(最后一个,当意志减速参数是“代码> < < /代码>”)您应该将

UIScrollView
contentOffset
参数设置到所需的位置

您还可以通过检查scrollview的
contentOffset
属性来了解当前位置,然后计算所需的最近区域


虽然您不必创建自己的滚动控件,但您必须手动滚动到所需的位置

要添加到felipe所说的内容,我最近创建了一个表视图,它以UIPicker类似的方式捕捉单元格。 聪明的scrollview委托绝对是实现这一点的方法(您也可以在uitableview上实现这一点,因为它只是uiscrollview的一个子类)

当scroll视图开始减速(即在调用ScrollViewDiEndDraging:WillDecreate:之后),响应scrollViewDidScroll:并使用上一个scroll事件计算差异时,我就完成了这项工作

当差异小于2到5个像素时,我会检查最近的单元格,然后等待该单元格经过几个像素,然后使用setContentOffset:animated:向另一个方向滚动。 这创造了一个很好的用户体验的小反弹效果,因为它提供了一个很好的捕捉反馈

当表在顶部或底部反弹时,您必须非常聪明,不要做任何事情(将偏移量与0或内容大小进行比较会告诉您这一点)。 在我的例子中,它工作得很好,因为单元格很小(大约80-100px高),如果您有一个包含较大内容区域的常规滚动视图,您可能会遇到问题。 当然,你不会总是减速通过一个单元格,所以在本例中,我只是滚动到最近的单元格,动画看起来很不稳定。事实证明,如果调整得当,这种情况几乎不会发生,所以我对此很冷静。 根据您的具体屏幕,花几个小时调整实际值,您可以得到一些不错的结果

我也尝试过这种幼稚的方法,调用setContentOffset:animated:on ScrollViewDiEndDecelling:但它会创建一个非常奇怪的动画(或者如果不设置动画,则会产生令人困惑的跳跃),减速率越低,情况就越糟(你将从一个缓慢的动作跳到一个更快的动作)

因此,要回答这个问题: -不,没有简单的方法可以做到这一点,需要花一些时间来润色上一个算法的实际值,这可能在你的屏幕上根本不起作用,
-不要试图创建自己的滚动视图,你只会浪费时间,糟糕地重新创造一个漂亮的工程苹果与卡车负载的错误创建。scrollview委托是解决问题的关键。

由于UITableView是UIScrollView子类,因此可以实现UIScrollViewDelegate方法:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
    withVelocity:(CGPoint)velocity 
    targetContentOffset:(inout CGPoint *)targetContentOffset
然后计算所需的最接近的目标内容偏移量,并在inout CGPoint参数上设置该偏移量

我刚刚试过这个,效果很好

首先,检索非导向偏移,如下所示:

CGFloat unguidedOffsetY = targetContentOffset->y;
- (void) snapScroll;
{
     int temp = (theScrollView.contentOffset.x+halfOfASubviewsWidth) / widthOfSubview;
    theScrollView.contentOffset = CGPointMake(temp*widthOfSubview , 0);
}

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    if (!decelerate) {
        [self snapScroll];
    }
}

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self snapScroll];
}
然后通过一些数学计算,找出你想要的位置,注意表格标题的高度。下面是我代码中的一个示例,用于处理代表美国各州的自定义单元格:

CGFloat guidedOffsetY;

if (unguidedOffsetY > kFirstStateTableViewOffsetHeight) {
    int remainder = lroundf(unguidedOffsetY) % lroundf(kStateTableCell_Height_Unrotated);
    log4Debug(@"Remainder: %d", remainder);
    if (remainder < (kStateTableCell_Height_Unrotated/2)) {
        guidedOffsetY = unguidedOffsetY - remainder;
    }
    else {
        guidedOffsetY = unguidedOffsetY - remainder + kStateTableCell_Height_Unrotated;
    }
}
else {
    guidedOffsetY = 0;  
}

targetContentOffset->y = guidedOffsetY;

离题说明:正如您可能猜到的,“log4Debug”语句只是日志记录。顺便说一句,我使用的是Lumberjack,但我更喜欢旧Log4Cocoa中的命令语法。

试试下面的方法:

CGFloat unguidedOffsetY = targetContentOffset->y;
- (void) snapScroll;
{
     int temp = (theScrollView.contentOffset.x+halfOfASubviewsWidth) / widthOfSubview;
    theScrollView.contentOffset = CGPointMake(temp*widthOfSubview , 0);
}

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    if (!decelerate) {
        [self snapScroll];
    }
}

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self snapScroll];
}
这充分利用了整数在小数点后的下降。还假设所有视图都从0,0开始排列,只有contentOffset使其显示在不同的区域中


注意:连接代理,这样做非常好。你得到了一个修改版本-我的只是实际的常量lol。我重命名了变量,这样你就可以轻松阅读了

谢谢@kra,这肯定会创建一个更平滑的动画,滚动视图感觉更自然!按下可滚动的viewcontroller时,contentOffset将考虑UINavigationBar高度和原点。(不确定它为什么这样做,因为这毫无意义,但它就是这样做的)