转发UIGesture到后面的视图

2020/12/01 07:11 · ios ·  · 0评论

我正在使用iPhone(iOS 4.0或更高版本)应用程序,并且在多个视图之间进行触摸处理时遇到了一些麻烦。我有这样的视图结构

---> A superView 
     |
     ---> SubView - A 
     |
     ---> SubView - B (exactly on top of A, completely blocking A).

在此处输入图片说明

基本上,我有一个superView以及同级子视图A和B。B与A具有相同的框架,因此完全隐藏了A。

现在我的要求是这个。

  1. SubView B应该会收到所有滑动和点击(单次和两次)手势。
  2. SubView A应该会收到所有的捏合手势。

这就是我向视图添加手势识别器的方式

UISwipeGestureRecognizer *leftSwipe  =  [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(leftSwipe:)];
[leftSwipe setDirection:(UISwipeGestureRecognizerDirectionLeft)];
leftSwipe.delegate  =   self;
[bView addGestureRecognizer:leftSwipe];
[leftSwipe release];

UISwipeGestureRecognizer *rightSwipe  =  [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(rightSwipe:)];
[rightSwipe setDirection:(UISwipeGestureRecognizerDirectionRight)];
rightSwipe.delegate   =   self;
[bView addGestureRecognizer:rightSwipe];
[rightSwipe release];

UIPinchGestureRecognizer *pinch   =  [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
pinch.delegate    =   self;
[aView addGestureRecognizer:pinch];
[pinch release];

我做了一些研究,对我来说UIGestureRecognizerDelegate很有前途,我实现了委托方法

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

我为SubView B返回了NO,希望底层视图能够得到这些事件。虽然没有运气

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if ([gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] && [gestureRecognizer view] == bView) {
        NSLog(@"pinchGesture");
        //bView.userInteractionEnabled = NO;
        return NO;
    }
    return YES;
}

然后,我在委托回调(在上面的块中的注释代码)中禁用了SubView B的用户交互,当识别到捏手势时,希望SubView A会收到手势的其余部分。那里也没有这种运气。

所以这就是我现在站在的地方。我已经看到了这个问题,可接受的答案涉及财产cancelsTouchesInView但是我相信cancelsTouchesInView只能取消特定的触摸事件,不转发它。

还有其他方法可以满足我的要求吗?无论您提供什么提示,我都准备工作。

编辑:赏金时间

我所谓的subView A实际上是第3方库的View类的一个实例,它消除了所有接触,并且我对其上的任何手势都没有任何控制权。我想要左右滑动使用不同的实现方式,并且想要捏合,点击等工作,就像使用此第三方视图一样。因此,我将视图放在A(子视图B)的​​顶部以左右滑动。但是现在我想将其他手势事件转发到基础库。

如果我无法正确理解您的问题,则可以仅添加另一个具有rect的清晰视图,与您的A和B视图相同,并在其上实现所有手势:捏捏手势时,控制subView A,滑动并点击( double)手势-控制SubViewB。您可以通过不同的方式进行操作:通过指针或仅向类中的方法发送获取的手势,即可控制您的子视图。

例如:

UISwipeGestureRecognizer *leftSwipe  =  [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(leftSwipe:)];
[leftSwipe setDirection:(UISwipeGestureRecognizerDirectionLeft)];
leftSwipe.delegate  =   subViewAcontroller;
[clearView addGestureRecognizer:leftSwipe];
[leftSwipe release];

UISwipeGestureRecognizer *rightSwipe  =  [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(rightSwipe:)];
[rightSwipe setDirection:(UISwipeGestureRecognizerDirectionRight)];
rightSwipe.delegate   =   subViewAcontroller;
[clearView addGestureRecognizer:rightSwipe];
[rightSwipe release];

UIPinchGestureRecognizer *pinch   =  [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
pinch.delegate    =   subViewBcontroller;
[clearView addGestureRecognizer:pinch];
[pinch release];

要么:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if ([gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]]) {
        NSLog(@"pinchGesture");
        [subViewBcontroller solvePinchGesture: gestureRecognizer];
    }
//etc
    return YES;
}

捏手势将不会被aView接收,因为您的视图层次结构不正确。

---> A superView 
 |
 ---> SubView - A 
 |
 ---> SubView - B (exactly on top of A, completely blocking A).

bView将捕获所有的多点触摸,包括捏手势,但bView将不处理捏手势,因此它将把它传递给Responder链中的Next响应者,即bView的superView或bView的viewController。pinch事件永远不会传递到其兄弟视图,因为它们是并行的(没有父子关系或view-viewController关系)。

您可以按以下方式更改视图层次结构:

---> A superView 
 |
 ---> SubView - A 
       |
       ---> SubView - B (child view of b, exactly on top of A, completely blocking A)



- (void)viewDidLoad {
    [super viewDidLoad];

    aView = [[UIView alloc] initWithFrame:self.view.bounds];
    aView.backgroundColor = [UIColor blueColor];

    bView = [[UIView alloc] initWithFrame:self.view.bounds];
    bView.backgroundColor = [UIColor redColor];

    [self.view addSubview:aView];
    [aView addSubview:bView];

    UISwipeGestureRecognizer *leftSwipe  =  [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(leftSwipe:)];
    [leftSwipe setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    leftSwipe.delegate  =   self;
    [bView addGestureRecognizer:leftSwipe];

    UISwipeGestureRecognizer *rightSwipe  =  [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(rightSwipe:)];
    [rightSwipe setDirection:(UISwipeGestureRecognizerDirectionRight)];
    rightSwipe.delegate   =   self;
    [bView addGestureRecognizer:rightSwipe];

    UIPinchGestureRecognizer *pinch   =  [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
    pinch.delegate    =   self;
    [aView addGestureRecognizer:pinch];
}

请从以下链接获取更多信息:https :
//developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/EventsiPhoneOS/EventsiPhoneOS.html#//apple_ref/doc/uid/TP40009541-CH2-SW1

->响应者链中传递的事件的重要说明“当系统传递一个触摸事件时,它首先将其发送到特定的视图。对于触摸事件,该视图是hitTest:withEvent :;返回的视图; -运动事件,远程控制事件,操作消息和编辑菜单消息,该视图是第一响应者。如果初始视图不处理事件,它将沿着特定路径在响应者链中向上移动:

  1. 命中测试视图或第一响应者将事件或消息传递给其视图控制器(如果有);如果视图没有视图控制器,则它将事件或消息传递给其父视图。
  2. 如果视图或其视图控制器无法处理事件或消息,则将其传递给视图的超级视图。
  3. 如果层次结构中的每个后续超级视图无法处理事件或消息,则遵循前两个步骤中描述的模式。
  4. 如果视图层次结构中最顶层的视图无法处理事件或消息,则将其传递给窗口对象以进行处理。
  5. 如果UIWindow对象不处理事件或消息,则将其传递给单例应用程序对象。”

我上面的回答不是唯一的解决方案,您需要做的是在同一响应者链中进行滑动和捏捏手势处理逻辑,因此未处理捏捏手势事件将传递给正确的响应者。例如,您可以省略子视图b,并将向左/向右滑动手势添加到aView的superView中。

我前段时间做了类似的事情。我想用一根手指和两根或更多根手指做两件事。我的解决方案可能需要为您做一些调整,并且我不能确保所有代码在您的代码环境中都能正常工作。我没有找到hitTest的正确文档,也找不到为什么连续多次调用它。因此,我进行了一些测试,得出了一个解决方案,如何分离一个和多个手指的手势,这非常适合我的需求。

我有这个视图层次结构:

---> A superView 
 |
 ---> ScrollView - A - all touches
 |
 ---> ScrollView - B - only two+ finger scroll (exactly on top of A, completely blocking A).

我在superView的hitTest中实现了该开关:

BOOL endDrag; // indicates scrollviewB did finish
BOOL shouldClearHitTest; // bool to help calling the method clearHitTest only once.
BOOL multiTouch; // needed for the method clearHitTest to know if a multi-touch is detected or not
NSMutableArray *events; // store all events within one eventloop/touch;


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!endDrag) {
        if (!shouldClearHitTest) { // as hitTest will be called multible times in one event-loop and i need all events, i will clean the temporaries when everything is done
            shouldClearHitTest = YES;
            [[NSRunLoop mainRunLoop] performSelector:@selector(clearHitTest) target:self argument:nil order:1 modes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
        }
        [events addObject:event]; // store the events so i can access them after all hittests for one touch are evaluated

        if (event.type == UIEventTypeTouches && ([_events count] > 3 || [[event allTouches] count] > 0 || _currentEvent)) { // two or more fingers detected. at least for my view hierarchy
            multiTouch = YES;
            return scrollViewB;
        }
    }else {
        endDrag = NO;
    }
    return scrollViewA;
}

- (void)clearHitTest {
    if (shouldClearHitTest) {
        shouldClearHitTest = NO;
        [events removeAllObjects];
        if (multiTouch) {
           // Do some special stuff for multiTouch
        }
        multiTouch = NO;
    }
}

我建议您在需要的地方使用下面的代码行可能会帮助您。

//--->for bview gesture to detect swipe
[pinch requireGestureRecognizerToFail:leftSwipe]; && 
[pinch requireGestureRecognizerToFail:rightSwipe];

//--->for aview gesture to detect pinch
[rightSwipe requireGestureRecognizerToFail:rightSwipe]; ||
[leftSwipe requireGestureRecognizerToFail:pinch];

如果bView有捏手势。从bView的捏手势动作中,如果调用aView的捏手势动作,则...

UIPinchGestureRecognizer *pinchA   =  [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinchA:)];
[aView addGestureRecognizer:pinchA];
[pinchA release];    

UIPinchGestureRecognizer *pinchB   =  [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinchB:)];
[bView addGestureRecognizer:pinchB];
[pinchB release];


-(void)handlePinchA:(UIGestureRecognizer*)gestureRecognizer
{
NSLog(@"handlePinch on A");  
}

-(void)handlePinchB:(UIGestureRecognizer*)gestureRecognizer
{
NSLog(@"handlePinch on B");
[self handlePinchA:gestureRecognizer];  
}

aView是thirdParty库。您可以从外部调用handlePinchA方法吗?NSLog手势识别器将我打印为action = handlePinchA

NSLog(@"gestureRecognizers %@", [aView gestureRecognizers]);

打印我:

gestureRecognizers (
"<UIPinchGestureRecognizer: 0x8b3e500; state = Possible; view = <UIView 0x8b2f470>; target= <(action=handlePinchA:, target=....
本文地址:http://ios.askforanswer.com/zhuanfauigesturedaohoumiandeshitu.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!