2011년 4월 8일 금요일

[iOS] UINavigationController의 push/pop 애니메이션 변경하기

UINavigationController는 아이폰의 일반적인 네비게이션 UI를 쉽게 만들 수 있도록 해 준다. 물론 애니메이션도 필요하면 사용할 수 있다.

하지만 pushViewController:animated 혹은 popViewControllerAnimated:animated 를 사용할 때 애니메이션을 사용할지 여부만 고를 수 있지 애니메이션 종류를 고를 수는 없다. 무조건 좌/우로 플립되는 애니메이션만 사용할 수 있다.

그렇다고 해서 못 바꾸는 건 아니다. 약간의 노가다가 추가되면 원하는 에니메이션을 이용할 수 있다.

여기서는 예제로 페이지 넘기기 애니메이션을 적용해 보려고 한다.

push 시에는 간단하다. 일반적인 트랜지션(transition) 애니메이션을 사용하면 된다.
[UIView beginAnimations:@"anotheranimation" context:nil];
[someNavigationController pushViewController:someView 
                                    animated:NO];

[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown 
                       forView:someNavigationController.view
                         cache:NO];

[UIView setAnimationDuration:0.5];
[UIView commitAnimations];
핵심은 pushViewController 시 animated에 NO를 준 것. 그 외에는 일반적인 코드다.

위 코드를 이용하게 되면 새로운 뷰가 페이지가 내려오는 방식으로 애니메이션 되면서 표시된다.

하지만 반대로 pop 시에는 어떻게 하면 될까.

찾아보니 여러 방법에 대한 의견(?)이 있었다. 예를 들어 back 버튼을 변경할 때 selector를 달아서 거기서 수동으로 애니메이션 처리를 하는 방법 등...

하지만 내 경우 뭐가 문제인지 죽거나 동작 안하거나 전혀 반응 없거나 등의 결과를 얻었다.

그래서 최후의 수단을 사용하기로 했다. 바로 UINavigationController를 상속받아서 필요한 부분을 오버라이딩 해 버리는 방법.

아래 코드는 UINavigationController를 상속받은 CustomNavigationController 구현 코드이다.
@implementation CustomNavigationController

- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationDuration:0.5];
  [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
                         forView:self.view
                           cache:NO];

  UIViewController *viewController = [super popViewControllerAnimated:NO];
 
  [UIView commitAnimations];
 
  return viewController;
}

@end
꼭 필요한 popViewControllerAnimated만을 따로 오버라이딩 한 코드이다. 내용도 일반적인 트랜지션 애니메이션 코드. (animated 값을 체크해서 처리하는 부분은 필요하다면 구현해도 되겠다)

물론 push 시의 애니메이션도 CustomNavigationController 를 오버라이딩 해서 구현 할 수도 있다. (개인적으로 오버라이딩을 너무 많이 하는건 좋아하지 않아서 -_-;;;)

여담이지만, 페이지 넘기기 애니메이션은 네이게이션 스타일과는 안어울리는 것 같다. 왜 좌/우 플립을 기본 애니메이션으로 사용하는지 생각해보자. ;;

댓글 없음 :