【问题标题】:uiscrollview catch scroll attemptuiscrollview 捕捉滚动尝试
【发布时间】:2011-10-13 12:26:54
【问题描述】:

我正在使用 UIScrollView 子类,我只是想捕捉一个特定的事件,但我不知道如何处理它。 基本上我有一个水平的uiscrollview,它已经关闭了弹跳。当我滚动到滚动视图的任一端时,它应该会停止。但是现在我想捕捉一个事件,如果用户尝试在当前占用的内容结束的方向上滑动。即,如果用户一直向右滚动并尝试再次向右滑动,我该如何捕捉这个手势。

我尝试将手势识别器添加到 uiscrollview 子类,当它到达末尾时,它会关闭启用滚动功能,从而可以捕获这些手势。但是如果用户试图在可用的方向上滑动,滚动效果将不会在滚动关闭时发生。即当用户向右滚动,然后尝试向左滚动时,不会发生任何事情,因为滚动已关闭以捕捉可能的向右手势。

关于如何捕捉向特定方向滚动的尝试有什么想法吗? 谢谢

【问题讨论】:

    标签: iphone objective-c ios ios4


    【解决方案1】:

    捕获该事件的一种方法是将反弹设置为属性 YES 并在滚动视图子类中自己实现停止的反弹。通过覆盖 setContentOffset 方法,您可以替换它滚动到的坐标。发生这种情况时,您也可以让其他事情发生。

    -(void)setContentOffset:(CGPoint)contentOffset
    {
        CGPoint validOffset = [self validVersionOfOffset:contentOffset];
    
        if(contentOffset.x == validOffset.x)
        {
            [super setContentOffset:validOffset];
        }
        else
        {
            [super setContentOffset:validOffset animated:NO];
            [bounceCatchDelegate scrollViewTriedBouncing:self];
        }
    }
    
    -(void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
    {
        CGPoint validOffset = [self validVersionOfOffset:contentOffset];
        [super setContentOffset:validOffset animated:animated];
        if(contentOffset.x == validOffset.x)
        {
            [super setContentOffset:validOffset animated:animated];
        }
        else
        {
            [super setContentOffset:validOffset animated:NO];
            [bounceCatchDelegate scrollViewTriedBouncing:self];
        }
    }
    
    -(CGPoint)validVersionOfOffset:(CGPoint)offset
    {
        //Prevents bouncing at the left and right:
        offset.x = fminf(offset.x, self.contentSize.width-CGRectGetWidth(self.frame));
        offset.x = fmaxf(offset.x, 0.0f);
        return offset;
    }
    

    委托的使用只是一个建议,任何方法调用都可以。

    【讨论】:

    • 无法让它为我工作,但它肯定向我展示了未来工作的好主意,所以 +1
    • 我的 uiscrollview 子类是使用 @interface WallScrollView : UIScrollView {} 创建的,我将上面的 setcontentoffset 代码放入其中。这确实可以很好地捕获所有 setcontent 调用。但是 [super setcontentoffset:validoffset] 行对我来说崩溃了
    • 这很奇怪......我找不到任何错误,它对我来说很好......崩溃会给出什么信息?
    • 由于未捕获的异常'CALayerInvalidGeometry'而终止应用程序,原因:'CALayer bounds contains NaN: [nan nan; 480 320]'
    • 似乎 validOffset 搞砸了......我很难理解为什么会发生这种情况。我唯一的猜测是你的 WallScrollView 还没有框架,但这仍然没有什么意义......我所能做的就是祝你好运,我猜。
    【解决方案2】:

    这是一种解决方法,但您可以将 contentSize 设置得比实际更大。然后在 scrollViewDidScroll 委托方法中,您可以检查滚动视图的 contentOffset。如果它高于所需值,则将其设置回上限并随心所欲。也许它在视觉上看起来不会那么好,但它可以工作。很难说你的目标是什么。

    【讨论】:

    • 好吧,滚动视图占据了全屏,然后当用户尝试滑过内容时,我想将整个滚动视图移出屏幕并将其替换为其他视图。我会按照你的建议试一试,然后回复你
    【解决方案3】:

    有点像一起破解了一些东西,它并不漂亮,但可以工作

    从关闭弹跳开始

    使用 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{}

    我检查内容偏移量,如果在滚动视图的任一端,我将其标记为如此并将弹跳设置为打开。然后在

    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{}

    我还检查了这里的 contentoffset 并且它超出了滚动内容的任何一个末尾,然后关闭滚动并将内容视图设置为结束位置。下面是代码。非常凌乱,完全为它感到羞耻,但处理得不好。

    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    
        int t = self.contentOffset.x;
        if (t==0) {
            leftSet = YES;
            rightSet = NO;
            self.bounces = YES;
        } else if (t>=imagePosX-480) {//if scrollview reaches the end 
            rightSet = YES;
            leftSet = NO;
            self.bounces = YES;
        }
    
    }
    
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
        int t = self.contentOffset.x; 
    
        if (t<=0) {
            if (leftSet) {
                self.bounces = NO;
                self.scrollEnabled = NO;
    
                //perform code i wanted here
    
    
            }
    
    
        } else if (t>=imagePosX-480) {//if scrollview reaches the end then snap back to start
    
            if (rightSet) {
                self.bounces = NO;
                self.scrollEnabled = NO;
                //perform code i wanted here
    
            }
    
        }
        else{
            rightSet = NO;
            leftSet = NO;
            self.bounces = NO;
        }
    
    
    
    }
    

    我绝不推荐上述方法,但该死的,它确实有效,不幸的是有更大的鱼要炸。我接近于让异常的工作方式为我工作,当然看起来更干净,所以如果有人说他的作品不好,请投票作为答案。

    【讨论】:

      【解决方案4】:

      在我的情况下,我在使用后设置了 scrollView 的 contentSize:

          self.scrollView.minimumZoomScale = (self.scrollView.frame.size.width/self.scrollView.contentSize.width);
      

      这意味着一旦用户开始缩放滚动视图,就会触发 nan 并触发异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-20
        • 1970-01-01
        • 2021-07-10
        • 2020-04-02
        • 1970-01-01
        • 2010-11-23
        • 2013-08-04
        • 2014-12-27
        相关资源
        最近更新 更多