【问题标题】:Limiting the scrollable area in UIScrollView限制 UIScrollView 中的可滚动区域
【发布时间】:2011-04-27 18:30:59
【问题描述】:

我有一个 UIScrollView 正在滚动一个相当大的 UIView。

在某些时候我想限制用户可以滚动的区域。例如,我可能只想让他们查看视图的底部四分之一。

如果视图滚动得太远,我可以通过覆盖 scrollViewDidScroll 然后调用 setContentOffset 来限制区域。但是这种方式我不能让它像 UIScrollView 在滚动超出 UIView 的边界时那样平滑地反弹。

有没有更好的方法来限制 UIScrollView 中的可滚动区域?

【问题讨论】:

    标签: iphone uiscrollview


    【解决方案1】:

    Yoko 在 Swift 4 中的回答有一个小的改进是

    override func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y > 600 {
            let anim = UIViewPropertyAnimator(duration: 1, dampingRatio: 0.5) {
                scrollView.isScrollEnabled = false
                scrollView.setContentOffset(CGPoint(x: 0, y: 600), animated: false)
                scrollView.isScrollEnabled = true
            }
            anim.startAnimation()
        }
    }
    

    这将使滚动视图动画与其应该做的非常相似。当您在“反弹”区域时,较慢的拖动将不起作用,并且动画持续时间必须取决于距离(不是像这里那样恒定),如果您想要准确的话。您也可以尝试在scrollViewDidScroll 中执行此逻辑,看看它有何不同。关键是setContentOffset(_:,animated:) 必须带有 animated: false 以便UIViewPropertyAnimator 的块可以捕获它并对其进行动画处理

    【讨论】:

      【解决方案2】:

      另一种方法是覆盖UIScrollView的方法:

      - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event.

      返回YES 将允许用户滚动。返回NO 不会。

      注意:这将禁用对嵌入在UIScrollView 中的任何视图的所有触摸,pointInside 返回NO。如果您不想滚动的区域没有任何交互,则很有用。


      此示例仅允许在用户滚动UITableView 时滚动UIScrollView。 (一个UITableView 和两个UIViews 嵌入在UIScrollView 中)

      - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
          for (UIView *subview in self.subviews) {
              if ([subview pointInside:[self convertPoint:point toView:subview] withEvent:event] && ![subview isKindOfClass:[UITableView class]]) {
                  return NO;
              }
          }
          return YES;
      }
      

      【讨论】:

        【解决方案3】:

        我找到了适合我的东西。它让您滚动到点 0,0,但不能再进一步:

        - (void)scrollViewDidScroll:(UIScrollView *)scrollView
        {
            if (scrollView.contentOffset.x <= -1) {
                [scrollView setScrollEnabled:NO];
                [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
                [scrollView setScrollEnabled:YES];
            }
        }
        

        您可以对顶部、底部或右侧(x 或 y)执行相同操作

        【讨论】:

        • 这种方法的问题是你失去了“反弹”——你滚动到区域之外,当你放手时滚动会轻轻地弹回。
        • 废话你是对的,没有正确阅读。不过,也许这可以帮助其他人。
        【解决方案4】:

        我会将滚动视图的 contentSize 属性更改为您希望用户能够滚动的区域的大小,并调整子视图的 frame.origin,例如您想要的左上边界出现在 (0 , 0) 相对于滚动视图。例如,如果您的视图高度为 800 磅,并且您想显示底部四分之一,请将 contentSize 的高度设置为 200,并将 view.frame.origin 的 y 分量设置为 -600。

        【讨论】:

        • 您的回答正是我需要解决的类似问题的正确提示。基本上 uiscrollview.frame.size 和 uiscrollview.contentsize 之间的差异成为您允许的可滚动部分。您可以使用 uiview.frame 和 uiview.size 以任何您喜欢的方式使用放置在 uiscrollview 中的 uiview 以获得所需的效果。明白了这一点,生活就是美好的。快乐滚动! :)
        • 以下是封装类似逻辑的解决方案示例:github.com/ealeksandrov/EARestrictedScrollView
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-24
        • 1970-01-01
        • 1970-01-01
        • 2021-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多