UINavigationController에 UIGestureRecognizer 등록하기

사내에서 Path 2 리뷰를 했습니다.
리뷰 포스트는 여기를 누르시면 보실 수 있습니다.

포스트에 등록된 댓글에 UINavigationController에 UIGestureRecognizer 등록한 부분에 대한 상세한 설명 부탁하신 분에게 도움이 되었으면 합니다.
사실 퀵리뷰를 위한 Demo여서 견고하게 구현하지 않았고 설명에서 제외했었습니다. 참고하셔서 더 멋진 앱 만들어주세요. 🙂

 

1.UINavigationController를 상속받는 클래스를 생성합니다.

UINavigationController의 구조에 대한 Documentation을 보면 알겠지만 UINavigationController는 UINavigationController에 설정되는 rootViewController보다 상위. 즉, 부모 클래스입니다. 따라서 터치 등의 이벤트를 받는 UIResponder는 UINavigationController의 view를 먼저 거치게 됩니다.

2. 생성된 클래스의 – (void)loadView; 또는 -(void)viewDidLoad; 메소드에 UISwipeGestureRecognizer를 정의합니다. 물론 – (void)touchesBegin: 등의 터치 이벤트 관련 메소드로 정의를 하셔도 됩니다만 손이 많이 갈 수 있어서 좌/우 각각에 대한 UISwipeGestureRecognizer를 이용하였습니다.

- (void)loadView    {
    [super loadView];

    UISwipeGestureRecognizer *leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onList)];
    leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;

    [self.view addGestureRecognizer:leftSwipeGestureRecognizer];
    [leftSwipeGestureRecognizer release];

    UISwipeGestureRecognizer *rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onMenu)];
    rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;

    [self.view addGestureRecognizer:rightSwipeGestureRecognizer];
    [rightSwipeGestureRecognizer release];
}

 

3. 좌/우 Gesture에 따라 UINavigationController의 view의 frame 값을 애니메이션을 적용하여 변경합니다.

사실상 Path 2나 Facebook 앱처럼 Swipe 중인 status에 따라 view가 함께 움직이지는 않고 swipe 방향에 따라 바로 view가 움직이게 처리하였습니다. view가 함께 움직이게 하기 위해서는 현재 터치된 좌표를 얻어와 처리를 하면 가능하겠죠?

- (void)onList   {

    switch (_status) {
        case ViewStatusDefault:

            if (!_accessFriends) {
                return;
            }

            _status = ViewStatusMenu;
            [[[self.viewControllers objectAtIndex:0] view] setUserInteractionEnabled:NO];
            [UIView animateWithDuration:0.3f animations:^(void) {

                [self.view setFrame:CGRectMake(-280.0f, 0.0f, 320.0f, 480.0f)];
            }];
            break;

        default:

            _status = ViewStatusDefault;
            [[[self.viewControllers objectAtIndex:0] view] setUserInteractionEnabled:YES];
            [UIView animateWithDuration:0.3f animations:^(void) {

                [self.view setFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
            }];
            break;
    }
}

4. 이렇게 구현하시면 Swipe Gesture를 제외한 나머지 이벤트들은 UINavigationController의 현재 UIViewController에 전달되며, Swipe Gesture만 UINavigationController에서 구동합니다.

 

Comments (2)

  1. 자세한 설명 너무나 감사드립니다. 어제 질문을 해 놓고 혼자서 이리저리 해 보다가, 저는 그냥 UIViewController를 상속받아 구현해 보았습니다. 아무래도 UINavigationController를 상속 받아 내부 동작을 재정의하는게 마음에 걸려서요. Pan, Tap 제스처 인식기를 이용하여 swipe 동작에 따라 뷰가 이동하고, 일정 지점 이상 이동했으면 손을 뗐을 때 상태가 전환되게 했습니다. ^^;; 막상 부딪혀보니까 어떻게든 되네요. 저도 제 코드를 정리해서 블로그에 게시하고 트랙백을 남기도록 하겠습니다. 다시 한 번 좋은 글 감사드립니다.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.