2011-03-03 2 views
0

UINavigationControllerDelegate 프로토콜 사용과 관련하여 약간의 오해가있을 수 있습니다. 여기에 내 상황이있다 :UINavigationControllerDelegate 구현 문제

나는 ViewController를 가지고있다. PopViewViewroller를 표시 할 수있는 BViewController라고 부르 자. BViewController는 AViewController 다음에 NavigationContoller의 스택에있는 두 번째 ViewController입니다. 사용자가 BViewController의 버튼을 눌렀을 때 App이 이전 뷰인 AViewController로 돌아갈 때 PopoverViewController를 닫아야합니다.

그렇게하려면

, 나는 BViewController가있는 navigationController 안에 그러나 그이 프레임 워크에 의해 직접 호출되지 않는
- (void)viewWillDisappear:(BOOL)animated { 
    NSLog(@"BViewController will disappear"); 
    // Check whether the popoverViewController is visible 
    if (self.popoverController.popoverVisible==YES) { 
     [self.popoverController dismissPopoverAnimated:NO]; 
    } 
} 

BViewController

에서 다음을 구현했습니다. 따라서, 내있는 navigationController와 UINavigationControllerDelegate을 등록하고 다음과 같은 두 가지 방법을 구현 :

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 
    // Pass the message on to the viewController in question 
    [viewController viewWillAppear:animated]; 
} 

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 
    // Pass the message on to the viewController in question 
    [viewController viewWillDisappear:animated]; 
} 

그러나,이 두 방법에서의 ViewController의 매개 변수에 전달 된가 표시되기 전에 한 것 같다. 두 번째 방법을 사용하면 사라질 것으로 예상되는 액세스 권한을 얻을 수 있습니다. 그래서, 사용자가 앞에서 설명한 버튼을 눌렀을 때 viewWillDisappear는 AViewController에서 호출되고 BViewController에서는 사라질 것입니다. 그게 맞는 것 같니? 사과 설명서는 두 경우 모두를 참조합니다.

보기 및 탐색 항목 속성이 표시되는보기 컨트롤러입니다.

... 상당히 명확하지 않다고 생각합니다. 도움을 주셔서 감사합니다.

답변

2

두 개의 대리자 메서드는 모두 동일한 작업 (보기 컨트롤러 표시)에 대해 호출됩니다. navigationController: willShowViewController:animated:이며보다 앞에 있습니다. 새보기 컨트롤러가 gui에 표시됩니다. 새 뷰 컨트롤러가 표시된 후에 navigationController:navigationController didShowViewController:animated:이 호출됩니다.

이 패턴은 apple의 많은 위임 프로토콜에서 찾을 수 있습니다. 불행히도 NavigationViewController에 액션이 팝인지 푸시인지를 알려주는 델리게이트 메소드가 없다.

NavigationControllerDelegate.h : 다음 약 및 쪽에서 알 나는 내 자신의 프로토콜에 훅

+0

감사합니다. 그것은 의미가 있지만 그럼에도 불구하고 조금 실망 스럽습니다. – McKrassy

0

,

@protocol NavigationControllerDelegate <NSObject> 
@required 
-(void) navigationController: (UINavigationController*) navController 
    willMoveFromViewController: (UIViewController*) from 
     toViewController: (UIViewController*) to; 
@end 

대신 일반 UINavigationViewController의, 그때 약간의 헬퍼 클래스를 사용하는

NavigationHandler.h :

@interface NavigationHandler : NSObject <UINavigationControllerDelegate> { 
    NSMutableArray* m_viewControllers; 
} 
뷰 컨트롤러를 추적 내 애플 대리자에서

, 나는 이러한 개체 중 하나를 만들고 탐색 컨트롤러의 대리인으로 설정 :

... 
m_navigationHandler = [[NavigationHandler alloc] init]; 
navigationController = [[UINavigationController alloc] initWithRootViewController: mainMenuViewController]; 
navigationController.delegate = m_navigationHandler; 
... 

그리고에서와 뷰 컨트롤러 내 자신의 목록을 비교의 간단한 경우에 무엇을 네비게이션 컨트롤러 :

NavigationHandler.m

#import "NavigationHandler.h" 
#import "NavigationControllerDelegate.h" 

@implementation NavigationHandler 

-(id) init { 
    if ((self = [super init])) { 
    m_viewControllers = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

-(void) dealloc { 
    [m_viewControllers release]; 
    [super dealloc]; 
} 

- (void)navigationController:(UINavigationController *)navController 
    willShowViewController:(UIViewController *)viewController 
       animated:(BOOL)animated { 

    // Find out which viewControllers are disappearing and appearing 

    UIViewController* appearingViewController = nil; 
    UIViewController* disappearingViewController = nil; 

    if ([m_viewControllers count] < [navController.viewControllers count]) { 

    // pushing 
    if ([m_viewControllers count] > 0) { 
     disappearingViewController = [m_viewControllers lastObject]; 
    } 
    appearingViewController = viewController; 
    [m_viewControllers addObject: viewController]; 

    } else if ([m_viewControllers count] > [navController.viewControllers count]) { 

    // popping 
    disappearingViewController = [m_viewControllers lastObject]; 
    appearingViewController = viewController; 
    [m_viewControllers removeLastObject]; 

    } else { 
    return; 
    } 

    // Tell the view that will disappear 
    if (disappearingViewController != nil) { 
    if ([disappearingViewController conformsToProtocol: @protocol(NavigationControllerDelegate)]) { 
     if ([disappearingViewController respondsToSelector: @selector(navigationController:willMoveFromViewController:toViewController:)]) { 
     UIViewController<NavigationControllerDelegate>* vcDelegate = (UIViewController<NavigationControllerDelegate>*)disappearingViewController; 
     [vcDelegate navigationController: navController willMoveFromViewController: disappearingViewController toViewController: appearingViewController]; 
     } 
    } 
    } 

    // Tell the view that will appear 
    if ([appearingViewController conformsToProtocol: @protocol(NavigationControllerDelegate)]) { 
    if ([appearingViewController respondsToSelector:@selector(navigationController:willMoveFromViewController:toViewController:)]) { 
     UIViewController<NavigationControllerDelegate>* vcDelegate = (UIViewController<NavigationControllerDelegate>*)appearingViewController; 
     [vcDelegate navigationController: navController willMoveFromViewController: disappearingViewController toViewController: appearingViewController]; 
    } 
    } 
} 

@end 
+0

작동합니까 ...? –