Xamarin UIScrollView GestureRecognizerShouldBegin 在滚动视图移动时报告速度为 0 [英] Xamarin UIScrollView GestureRecognizerShouldBegin reports velocity of 0 when scroll view is moving

查看:18
本文介绍了Xamarin UIScrollView GestureRecognizerShouldBegin 在滚动视图移动时报告速度为 0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Xamarin 开发一个 iOS 应用程序,我想继承 UIScrollView 以便根据滚动视图的速度处理平移手势.因此,我覆盖了 GestureRecognizerShouldBegin 并检查了平移手势的 VelocityInView.这适用于第一个手势,但在滚动视图运动(减速)时触发的后续平移手势始终报告速度为 (0, 0):

I'm using Xamarin to develop an iOS app and I want to subclass UIScrollView in order to handle the pan gesture in the scroll view based on its velocity. So, I made an override of GestureRecognizerShouldBegin and I check the VelocityInView of the pan gesture. This works fine for the first gesture, but subsequent pan gestures that fire while the scroll view is in motion (decelerating) always report a velocity of (0, 0):

public class MyScroll : UIScrollView
{
    public override bool GestureRecognizerShouldBegin(UIGestureRecognizer gestureRecognizer)
    {
        UIPanGestureRecognizer panGesture = gestureRecognizer as UIPanGestureRecognizer;
        if (panGesture != null)
        {
            CGPoint velocity = panGesture.VelocityInView(this);
            Console.WriteLine("Pan gesture velocity: " + velocity);
        }
        return true;
    }
}

在滚动时平移一次然后第二次后输出:

Output after panning once and then a second time while the scroll is in motion:

Pan gesture velocity: {X=37.92359, Y=-872.2426}
Pan gesture velocity: {X=0, Y=0}

这是一个错误还是预期的行为?

Is this a bug or is this the expected behavior?

在 Xamarin 的论坛上交叉发布:https://forums.xamarin.com/discussion/54478/uiscrollview-pan-gesture-velocity-reporting-0-if-it-is-already-moving#latest

cross-posted on Xamarin's forum: https://forums.xamarin.com/discussion/54478/uiscrollview-pan-gesture-velocity-reporting-0-if-it-is-already-moving#latest

编辑以澄清:

澄清我最终要做什么:我在水平分页视图中有一个垂直滚动视图.我想检查平移的速度,以便如果平移是水平的"(即 X 速度 > Y 速度),我可以告诉滚动视图不处理该手势.默认行为是,一旦滚动视图处于运动状态,另一个手势仍会滚动,但这使得用户很难水平滚动(跨页面),直到垂直滚动完全稳定.

To clarify what I'm ultimately trying to do: I have a vertical scroll view inside a horizontal paging view. I want to check the velocity of the pan so that I can tell the scroll view to not handle that gesture if the pan is "horizontal" (i.e., X velocity > Y velocity). The default behavior is such that once the scroll view is in motion, another gesture still scrolls, but this makes it difficult for users to scroll horizontally (across pages) until the vertical scroll has completely settled.

推荐答案

我终于想通了.感谢@RobertN 的帮助 :)

I finally figured it out. Thanks to @RobertN for his assistance :)

关键是滚动视图使用的默认平移手势识别器如果它已经在运动中将始终报告 0 速度(例如,前一个手势的惯性仍然有效).添加新的 UIPanGestureRecognizer 是记录后续手势实际"速度的好方法,但到那时影响原始平移手势的 GestureRecognizerShouldBegin 为时已晚.所以我所要做的就是向我的新 UIPanGestureRecognizer 添加一个 ShouldBegin 委托,并使用 that 返回 false我希望手势落入"父寻呼机的情况.

The key is that the default pan gesture recognizer used by the scroll view will always report 0 velocity if it is already in motion (e.g., the inertia from a previous gesture is still in effect). Adding a new UIPanGestureRecognizer is a good way to record the "actual" velocity of a subsequent gesture, but by that time it is too late to affect the original pan gesture's GestureRecognizerShouldBegin. So all I have to do is add a ShouldBegin delegate to my new UIPanGestureRecognizer and use that to return false in the case where I want the gesture to "fall through" to the parent pager.

        public MyScroll() : base()
        {
            UIPanGestureRecognizer panGesture = new UIPanGestureRecognizer();

            panGesture.ShouldBegin = delegate(UIGestureRecognizer recognizer)
            {
                CGPoint v = panGesture.VelocityInView(this);

                if (v.X != 0 || v.Y != 0)
                {
                    if (Math.Abs(v.X) > Math.Abs(v.Y))
                    {
                        return false;
                    }
                }

                return true;
            };

            this.AddGestureRecognizer(panGesture);
        }

这种方式,我只是让默认的滚动视图平移手势识别器做它的事情,而我的新 UIPanGestureRecognizer 识别用户何时做出新的水平手势,并通过该手势,以便寻呼机可以寻呼.这使得父分页器和垂直页面滚动视图的组合可以很好地一起运行(想象一下具有垂直滚动页面并且能够翻阅页面,即使垂直页面在运动中).请注意,您还需要实现以下方法以允许两个手势识别器同时操作:

This way, I just let the default scroll view pan gesture recognizer do its thing, while my new UIPanGestureRecognizer recognizes when the user is making a new horizontal gesture, and passes that one through so that the pager can page. This makes the combination of the parent pager and vertical page scroll views operate nicely together (imagine having vertically scrolling pages and being able to flip through pages, even if the vertical page is in motion). Note, you also need to implement the following method to allow both gesture recognizers to operate simultaneously:

        [Export("gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:")]
        public bool ShouldRecognizeSimultaneously(UIGestureRecognizer gestureRecognizer, UIGestureRecognizer otherGestureRecognizer)
        {
            return true;
        }

这篇关于Xamarin UIScrollView GestureRecognizerShouldBegin 在滚动视图移动时报告速度为 0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆