将触摸事件发送到堆叠在后面的UIviewController

时间:2013-01-06 10:21:54

标签: iphone ios uiview hittest

在我的应用中,我有2个透明的UIViewController图层。 第一层包含UIView对象,我试图通过触摸来识别:

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

方法

问题是, 它上方有一个透明的UIViewController

我尝试在SeconedStackedViewController上实现触摸事件,并创建FirstStackedViewController的实例并从那里调用相同的方法。这些方法被调用,但命中测试没有。

代码:

FirstStackedViewController *fsvc = [[FirstStackedViewController alloc]init];


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
      [fsvc hitTest:point withEvent:event];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
      fsvc = [[FirstStackedViewController alloc]init];
      [fsvc touchesEnded:touches withEvent:event];
}

如何覆盖FirstStackedViewController上要调用的此方法? 如果我可以模仿FirstStackedViewController上的触摸,我认为它会使作品

2 个答案:

答案 0 :(得分:2)

我的第一个问题是你推动透明视图控制器的原因。通过在同一个控制器中分层透明的视图,可以更好地满足您的需求吗?

不看你的要求,很难肯定地说,但很可能这更符合通常的逻辑分离:你需要能够从一个视图接收输入并将其传递给其他逻辑的代码。它需要了解两者的内部结构,因此对于具有完成任务所需知识的控制器对象来说是一个很好的选择。

在这种情况下,你可以毫无困难地 - 只需出示你的透明视图,并将触摸传递给你想要的任何动作。

但是有充分的理由使用透明视图来创建VC。要访问您下方的VC,您可以作为另一个响应者说访问应用程序代理。我会保留app委托,只需访问self.navController.viewControllers。该数组代表VC的堆栈。然后向下迭代 - 下面的'你'是你想要传递消息的那个。

很可能不是使用isMemberOfClass而是要定义协议并检查VC是否符合ToProtocol。

for (int i=0; i < navBar.viewControllers.count ; i++) {
   UIViewController *current = navBar.viewControllers[i];
   if (current == self) {
      UIViewController *targetVC = navBar.viewControllers[i+1]; // make sure you're not over bounds - you could do this in the loop def'n.
      if ([targetVC class] conformsToProtocol("TransparentPassingActions")]) {
         // pass message
      }
   }
}

我想你也可以使用indexOfObject来获取当前的VC,然后再看一下。这摆脱了循环。

顺便提一下,上一个答案中的伪代码会混淆UIViews和UIViewControllers;或许这对你来说很清楚。通过访问视图无法访问视图控制器。

答案 1 :(得分:1)

我首先要参考rootViewController。我假设您的层次结构是root - &gt;第一个视图控制器 - &gt;第二个视图控制器,然后通过启动fsvc,您正在创建一个新实例,而您实际上并没有从视图层次结构中获取引用。

我建议迭代rootviewcontroller子视图并找到第一个viewcontroller的实例,然后在该实例上调用该方法。

//PSEUDO-Code for class names, but iteration should solve the problem.
if(UIView *view in RootViewController.subviews){
     if(view isMemberOfClass: [FirstStackedViewController class]]){
          [(FirstStackedViewController *)view touchesEnded:touches withEvent:event];
     }
}

//ToolUser was right about mixing up VCs and regular Views, you'd want to do this:
for(UIViewController *vc in self.navigationController.viewControllers){
        if(view isMemberOfClass: [FirstStackedViewController class]]){
              [(FirstStackedViewController *)vc touchesEnded:touches withEvent:event];
         }
}