3

如何获得对触摸视图的 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 。如何获取对包含此视图而不是仅 UIView 的 UIViewController 的引用?

4

2 回答 2

0

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

有关详细信息,请参阅UIResponder 类参考。(UIViewController并且UIView是 的子类UIResponder。)

在您的情况下,由于您碰巧知道这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;
于 2012-07-29T17:11:32.170 回答
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
于 2012-07-29T18:37:23.370 回答