8

我在转发手势和触摸时遇到了一些麻烦。我玩了很多次,但我无法让它按照我想要的方式工作。

基本上我想用两根手指控制双屏上的滚动视图,并将其他所有内容转发到覆盖滚动视图后面的 ipad 视图。

为了能够控制双屏上的滚动视图,我将其子类化UIScrollView并添加为具有清晰背景的覆盖视图到 ipad 屏幕。

然后我将它与一个委托连接起来,将它的拖动和内容转发到双屏上的滚动视图。这完美地工作。

正如我所写,我希望滚动视图仅响应 2 个手指滚动,所以我将其设置为

ScrollView.panGestureRecognizer.minimumNumberOfTouches = 2;

但是滚动视图会吃掉所有的触摸,除了 2 根手指触摸到后面的视图之外,我没有正确转发其他所有内容。我认为覆盖

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

必须做到这一点,但我无法正确检测屏幕上的手指数量。

4

4 回答 4

5

我想分享/解释问题的解决方案。也就是说,我还想指出,hatfinch 的输入将我引向了正确的方向。非常非常感谢你,伙计!

尝试将视图/滚动视图作为覆盖顶层时的问题是顶层不知道它的“下一个响应者”。将视图/滚动视图作为底层视图将解决此问题。您可能需要微调该底层滚动视图中任何滚动视图的触摸行为以使行为正确(例如设置最大触摸次数)

解决方案是将 UIScrollview 子类化,覆盖此方法 覆盖 touchesBegan: 和其他触摸方法如下(参见 user1085093 答案),并将其作为底层视图添加到 ipad 屏幕。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
if (!self.dragging){
    [self.nextResponder touchesBegan: touches withEvent:event];
}
else{
    [super touchesBegan: touches withEvent: event];
}}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
if (!self.dragging){
    [self.nextResponder touchesMoved: touches withEvent:event];
}
else{
    [super touchesMoved: touches withEvent: event];
}}


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
if (!self.dragging){
    [self.nextResponder touchesEnded: touches withEvent:event];
}
else{
    [super touchesEnded: touches withEvent: event];
}}

我像这样设置了滚动视图:

 TopLayerScrollView *newScrollView = [[TopLayerScrollView alloc] init];
[newScrollView setBackgroundColor:[UIColor clearColor]];
[newScrollView setFrame:self.tabBarController.view.frame];
[newScrollView setContentSize:dualScreenViewController.scrollContent.contentSize];
newScrollView.showsHorizontalScrollIndicator = NO;
newScrollView.showsVerticalScrollIndicator = NO;
newScrollView.delegate = self;
newScrollView.bounces = NO;
[newScrollView scrollsToTop];
newScrollView.panGestureRecognizer.minimumNumberOfTouches = 2;

self.topLayerScrollView = newScrollView;
[newScrollView release];

[self.tabBarController.view removeFromSuperview];
[topLayerScrollView addSubview:self.tabBarController.view];
[window addSubview:topLayerScrollView];
[topLayerScrollView bringSubviewToFront:self.tabBarController.view];

底层滚动视图的委托方法:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.dragging || scrollView.tracking)
{
    [dualScreenViewControlleremphasized text.scrollContent setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y) animated:NO];
    self.tabBarController.view.frame = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, self.tabBarController.view.frame.size.width, self.tabBarController.view.frame.size.height);
}}

这个解决方案效果很好。另一种解决方案是像我最初打算的那样将滚动视图作为覆盖视图。如前所述,问题是让顶层视图知道它下面的视图(nextResponder)。要实现这一点,您必须继承 UIScrollview 并创建一个 UIResponder-property,您必须在您的 interface-builder 文件中或在运行时连接。这样,覆盖的滚动视图将知道谁是下一个响应者。 请看晨星的回答

于 2013-11-04T11:22:04.367 回答
2

不幸的是,您不能在-pointInside:withEvent:这里做任何事情,因为系统在确定触摸是否满足手势识别器的要求之前会决定触摸在哪个视图中(或触摸在哪个视图中)。

我认为您最好的选择是让当前位于滚动视图后面的视图实际上是滚动视图的内容视图,并在每次滚动视图的内容偏移发生变化时移动该视图以使其保持在相同的位置屏幕。(这听起来很昂贵,但实际上并非如此。)因此,您的滚动视图与其说是叠加层,不如说更像是一个底层。

您可能还希望使用UIScrollView.delaysContentTouches,-[UIScrollView touchesShouldBegin:withEvent:inContentView:]等来改进行为。

于 2013-11-01T12:04:31.057 回答
1

在我的应用程序中,我需要单指触摸事件来转发到滚动视图的父视图控制器,同时仍然允许滚动视图放大/缩小。

使用下一个响应者不起作用,因为我还添加了另一个覆盖视图,最终成为下一个响应者并窃取了触摸事件。我最终根据汤姆的回答做了一些事情,只需传入父视图控制器并将触摸事件直接发送给它。这是在斯威夫特:

class CustomScrollView: UIScrollView {

    var parentViewController: UIViewController?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        parentViewController?.touchesBegan(touches, with: event)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        parentViewController?.touchesMoved(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        parentViewController?.touchesEnded(touches, with: event)
    }
}
于 2017-04-12T06:22:05.210 回答
1

Xcode 6.4、Swift 1.2 的更新:

我还细分了UIScrollView

import UIKit

class WBMScrollView: UIScrollView
{
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
    {
        self.nextResponder()?.touchesBegan(touches, withEvent: event)
        super.touchesBegan(touches, withEvent: event)
    }
}

在应用程序 main vcViewController.swift中,我对其进行了测试:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        println(" touches began")
    }

它奏效了。滚动视图已通过 IB 添加并连接到ViewController.swift

于 2015-07-09T09:01:26.490 回答