Xamarin UIScrollView GestureRecognizerShouldBegin 在滚动视图移动时报告速度为 0 [英] Xamarin UIScrollView GestureRecognizerShouldBegin reports velocity of 0 when scroll view is moving
问题描述
我正在使用 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屋!