我有一个UIScrollView,高度约为600像素,宽度为320像素。所以我允许用户垂直滚动。
我也试图捕捉视图上的水平滑动。问题似乎是当用户用一些意外的垂直移动水平滑动时,UIScrollView会滚动并且我的touchesEnded委托方法永远不会被调用。
这是我的代码:
- (void)touchesEnded: (NSSet *)touches withEvent: (UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self];
if (currentPosition.x + 35 < gestureStartPoint.x)
{
NSLog(@"Right");
}
else if (currentPosition.x - 35 > gestureStartPoint.x)
{
NSLog(@"Left");
}
else if (!self.dragging)
{
[self.nextResponder touchesEnded: touches withEvent:event];
}
[super touchesEnded: touches withEvent: event];
}
有人知道即使涉及垂直拖动我也能如何工作吗?
答案 0 :(得分:4)
UIScrollView
尝试根据触摸开始后立即的移动来确定哪些触摸传递到其内容,哪些是滚动。基本上,如果触摸看起来像是立即滚动,它会处理该手势并且内容永远不会看到它;否则,手势会通过(第一次触摸的延迟很短)。
根据我的经验,我已经能够在处理垂直滚动的UIScrollView
的内容中捕获水平滑动 - 它基本上只对我有用。我通过将contentSize
设置为与滚动视图frame
的宽度相同来完成此操作,这足以告诉UIScrollView
它不会处理水平滚动。
但听起来你的默认行为有问题。一个硬件问题是,在笔记本电脑的触控板上模拟手指滑动非常困难。如果我是你,我会使用鼠标或最好在设备本身上测试默认的UIScrollView
设置。我发现这些输入法在输送滑动方面效果更好。
如果这不起作用,这是Apple的UIScrollView
文档中非常相关的段落:
因为滚动视图没有滚动条,所以它必须知道触摸是否表示要滚动的意图与跟踪内容中的子视图的意图。为了做出这种确定,它通过启动计时器暂时拦截触碰事件,并且在计时器触发之前,查看触摸手指是否进行任何移动。如果时间在没有显着位置变化的情况下触发,则滚动视图将跟踪事件发送到内容视图的触摸子视图。如果用户在计时器过去之前将手指拖得足够远,则滚动视图会取消子视图中的任何跟踪并执行滚动操作。子类可以覆盖touchesShouldBegin:withEvent:inContentView:,pagingEnabled和touchesShouldCancelInContentView:方法(由滚动视图调用),以影响滚动视图处理滚动手势的方式。
总之,您可以通过继承UIScrollView
并覆盖建议的方法来尝试他们的建议。
答案 1 :(得分:1)
如果@ Tyler的方法不起作用,请尝试在UIScrollView上放置一个视图,并在该视图的touchesBegan中处理任何水平滑动,并将垂直滑动传递给下一个响应者。你可以稍微模糊一点,处理水平移动比水平移动更多的任何东西,并将更纯粹的垂直滑动传递给UISCrollView(通过nextResponder)。
答案 2 :(得分:0)
Swift 4解决方案
在视图控制器的viewDidLoad()中注册两个手势识别器
let leftGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:)))
leftGesture.direction = .left
leftGesture.delegate = self
view.addGestureRecognizer(leftGesture)
let rightGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:)))
rightGesture.direction = .right
rightGesture.delegate = self
view.addGestureRecognizer(rightGesture)
执行滑动操作
@objc func handleSwipe(_ sender: UISwipeGestureRecognizer) {
// do swipe left/right based on sender.direction == .left / .right
}
为了同时进行水平滑动和垂直滚动,请让您的视图控制器实现UIGestureRecognizerDelegate
class MyViewController: UIViewController, UIGestureRecognizerDelegate
...
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
最后一步解决了以下问题:当您在y轴上移动+/- 5个像素以上时,“滚动”视图将接管并开始垂直滚动。