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];

ジェスチャ認識エンジンを使用してトリガーされたトリガーされたアクションでは、reckearizer.view を使用してパラメーターからビューを取得できます。

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

しかし、私が本当に必要としているのは、触れたビューの基礎となる UIViewController です。UIView だけでなく、このビューを含む UIViewController への参照を取得するにはどうすればよいですか?

4

2 に答える 2

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 に答える
0

[touchedView nextResponder]UIViewController管理するオブジェクトtouchedView(ある場合) またはtouchedViewのスーパービュー (管理するオブジェクトがない場合)を返しますUIViewController

詳細については、UIResponder クラス リファレンスを参照してください。(UIViewControllerUIViewは のサブクラスです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 に答える