【问题标题】:UIScrollView Adjust BouncinessUIScrollView 调整弹性
【发布时间】:2014-05-19 21:18:14
【问题描述】:

是否可以调整 UIScrollView 中的弹跳量?

例如,如果将滚动视图拖动到内容末尾 100pt 之外,则滚动视图会移动 50pt,我希望能够将相同拖动所经过的距离减少到 20pt。

我尝试了一些东西但没有成功。

在scrollViewDidScroll: 委托方法中调整contentOffset 似乎是不可能的,因为当设置值并且内容偏移接近零时,您会丢失原始滚动位置。

添加一个transform 将滚动视图反向转换为内容偏移的一部分似乎是个好主意。这会破坏所有的触摸跟踪并导致一系列问题。此外,在许多其他情况下,移动滚动视图会破坏视图的布局。

【问题讨论】:

    标签: ios objective-c cocoa-touch uiscrollview


    【解决方案1】:

    您可以做的一件事是使用 UIView + UIPanGestureRecognizer 制作自己的滚动视图。

    (有点过头了,这取决于你想要这个自定义效果有多糟糕。)

    这里是苹果rubber band algorithm的一个很好的解释。

    它的核心是:

    b = (1.0 – (1.0 / ((x * c / d) + 1.0))) * d
    
    where:
    
    x = distance from the edge
    
    c = constant value, UIScrollView uses 0.55
    
    d = dimension, either width or height
    

    然后您可以使用 c 和 x 的值来获得您想要的效果。

    一些代码 sn-p 帮助您入门:

    - (IBAction)handlePan:(UIPanGestureRecognizer *)sender
    {
        static CGRect beginRect;
    
        CGPoint translation = [sender translationInView:sender.view.superview];
        CGPoint velocity = [sender velocityInView:sender.view.superview];
    
        CGRect currentRect = CGRectOffset(beginRect, 0, translation.y);
    
        if (sender.state == UIGestureRecognizerStateBegan) {
            beginRect = sender.view.frame;
        }
        else if (sender.state == UIGestureRecognizerStateChanged) {
            if (currentRect.origin.y > self.naturalHidePosition) {
    
                CGFloat distanceFromEdge = currentRect.origin.y - self.naturalHidePosition;
                CGFloat height = CGRectGetHeight(sender.view.frame);
                CGFloat b = [self rubberBandDistance:distanceFromEdge dimension:height];
                currentRect.origin.y = self.naturalHidePosition + b;
            }
            else if (currentRect.origin.y < self.naturalShowPosition) {
    
                CGFloat distanceFromEdge = self.naturalShowPosition - currentRect.origin.y;
                CGFloat height = CGRectGetHeight(sender.view.frame);
                CGFloat b = [self rubberBandDistance:distanceFromEdge dimension:height];
                currentRect.origin.y = self.naturalShowPosition - b;
            }
    
            sender.view.frame = currentRect;
        }
        else if (sender.state == UIGestureRecognizerStateEnded) {
            if (velocity.y < 0) {
                currentRect.origin.y = self.naturalShowPosition;
            }
            else if (velocity.y > 0) {
                currentRect.origin.y = self.naturalHidePosition;
            }
            else if (currentRect.origin.y > (0.5 * (self.naturalShowPosition + self.naturalHidePosition))) {
                currentRect.origin.y = self.naturalHidePosition;
            }
            else {
                currentRect.origin.y = self.naturalShowPosition;
            }
    
            [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                sender.view.frame = currentRect;
            } completion:nil];
        }
    }
    
    
    - (CGFloat)rubberBandDistance:(CGFloat)distanceFromEdge dimension:(CGFloat)d
    {
        CGFloat c = 0.55;
        CGFloat b = (1.0 - (1.0 / ((distanceFromEdge * c / d) + 1.0))) * d;
        return b;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 2011-09-23
      • 1970-01-01
      相关资源
      最近更新 更多