2012-07-29 27 views
3

如何获得触摸视图的UIViewController的引用?UIGestureRecognizer - 获取对触摸的UIViewController的引用,而不是其视图?

我在UIViewController的视图上使用UIPanGestureRecognizer。以下是我初始化:

TaskUIViewController *thisTaskController = [[TaskUIViewController alloc]init]; 
    [[self view]addSubview:[thisTaskController view]]; 
    UIPanGestureRecognizer *panRec = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)]; 
    [[thisTaskController view] addGestureRecognizer:panRec]; 

在tiggered动作使用手势识别我能够得到从参数角度触发使用recognizer.view

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer { 
    UIView *touchedView = [[UIView alloc]init]; 
    touchedView = (UIView*)[recognizer view]; 
    ... 
} 

但是我真正需要的是触摸视图的底层UIViewController。我如何获得对包含此视图而不是仅UIView的UIViewController的引用?

回答

0

我要说的是,它更一个设计问题,而不仅仅是获得参考。所以我会遵循几个简单的建议:

  1. 业主应该从它的视角捕捉事件。即TaskUIViewController应该是您添加到其视图的UIPanGestureRecognizer的目标。
  2. 如果一个控制器有一个子控制器,并从其子控制器等待一些响应 - 将其作为委托实现。
  3. 你的“handlePan:”方法有内存泄漏。

这是解决您的问题的骨架:

@protocol CallbackFromMySubcontroller <NSObject> 
- (void)calbackFromTaskUIViewControllerOnPanGesture:(UIViewController*)fromController; 
@end 

@interface OwnerController : UIViewController <CallbackFromMySubcontroller> 
@end 

@implementation OwnerController 

- (id)init 
{ 
    ... 
    TaskUIViewController *thisTaskController = [[TaskUIViewController alloc] init]; 
    ... 
} 

- (void)viewDidLoad 
{ 
    ... 
    [self.view addSubview:thisTaskController.view]; 
    ... 
} 

- (void)calbackFromTaskUIViewControllerOnPanGesture:(UIViewController*)fromController 
{ 
    NSLog(@"Yahoo. I got an event from my subController's view"); 
} 

@end 


@interface TaskUIViewController : UIViewController { 
    id <CallbackFromMySubcontroller> delegate; 
} 
@end 

@implementation TaskUIViewController 

- (id)initWithOwner:(id<CallbackFromMySubcontroller>)owner 
{ 
    ... 
    delegate = owner; 
    ... 
} 

- (void)viewDidLoad 
{ 
    UIPanGestureRecognizer *panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    [self.view addGestureRecognizer:panRec]; 
    [panRec release]; 
} 

- (void)handlePan:(UIPanGestureRecognizer *)recognizer { 
    ... 
    [delegate calbackFromTaskUIViewControllerOnPanGesture:self]; 
    ... 
} 

@end 
+0

非常感谢。你写的东西对我来说很有意义。但是,使用UIViewController中的GesturerRecognizer,只要我用“EXC_BAD_ACCESS ...”错误触发pan事件,程序就会崩溃。不幸的是没有提供关于原因的更多提示。对此有何想法? – Bernd 2012-07-29 22:02:50

+0

只需检查您是否在手势中设置了正确的目标以及正确的处理程序。没有魔法,只是一个代码:) – SVGreg 2012-07-29 22:09:10

+0

我做到了,因为你提出了“UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan :)];”所有这些都在UIViewController的viewDidLoad方法中。 “handlePan”方法也存在...令人费解 – Bernd 2012-07-30 08:52:17

0

[touchedView nextResponder]将返回管理touchedViewUIViewController对象(如果有的话)或touchedView的上海华盈(如果它不有一个管理它UIViewController对象)。请参阅UIResponder Class Reference。 (UIViewControllerUIViewUIResponder子类)。

在你的情况,因为你碰巧知道touchedView是你的viewController的观点(而不是,例如,您的viewController的视图的子视图),你可以使用:

TaskUIViewController *touchedController = (TaskUIViewController *)[touchedView nextResponder]; 

在更一般的情况下,你可以工作了响应链,直到找到一种UIViewController中的对象:

id aNextResponder = [touchedView nextResponder]; 

while (aNextResponder != nil) 
{ 
    if ([aNextResponder isKindOfClass:[UIViewController class]]) 
    { 
    // we have found the viewController that manages touchedView, 
    // so we break out of the while loop: 
    break; 
    } 
    else 
    { 
    // we have yet to find the managing viewController, 
    // so we examine the next responder in the responder chain 
    aNextResponder = [aNextResponder nextResponder]; 
    } 
} 

// outside the while loop. at this point aNextResponder points to 
// touchedView's managing viewController (or nil if it doesn't have one). 
UIViewController *eureka = (UIViewController *)aNextResponder; 
+0

感谢。这看起来是正确的方向。我试图用这样的: TaskUIViewController * touchedController = [[TaskUIViewController alloc] init]; touchedController =(TaskUIViewController *)[touchedView nextResponder]; NSLog(@“Recognizer:%@”,touchedController); 我仍然得到一个指向UIView的指针而不是UIViewController。我说得对吗? – Bernd 2012-07-29 17:36:32

+0

@BerndPlontsch你不需要分配/初始化一个新的'TaskUIViewController'。只需使用TaskUIViewController * touchedController =(TaskUIViewController *)[touchedView nextResponder];'(请参阅我在上面的扩展答案中添加的示例代码。) – inwit 2012-07-29 18:06:34

相关问题