UIGestureRecognizer - 获取对触摸的UIViewController的引用而不是它的View?

时间:2012-07-29 16:59:27

标签: objective-c ios 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];

在使用手势识别器触发的触发动作中,我可以使用 recognizer.view

从参数中获取视图
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
    UIView *touchedView = [[UIView alloc]init];
    touchedView = (UIView*)[recognizer view];
    ...
}

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

2 个答案:

答案 0 :(得分:0)

[touchedView nextResponder]将返回管理UIViewController的{​​{1}}对象(如果有的话)或touchedView的超级视图(如果它没有touchedView管理它的对象。)

有关详细信息,请参阅UIResponder Class Reference。 (UIViewControllerUIViewControllerUIView的子类。)

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

touchedView

在更一般的情况下,你可以处理响应者链,直到找到一个类型为UIViewController的对象:

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

答案 1 :(得分:0)

我想说这不仅仅是一个参考设计问题。所以我会遵循几个简单的建议:

  1. 所有者应该从其视图中捕获事件。即TaskUIViewController应该是您添加到其视图中的UIPanGestureRecognizer的目标。
  2. 如果控制器有一个子控制器并从其子控制器等待一些响应 - 将其作为委托实现。
  3. 你的" handlePan中有内存泄漏:"方法
  4. 以下是解决问题的框架:

    @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