实现UINavigationControllerDelegate时出现问题

时间:2011-03-03 02:35:58

标签: ipad uiviewcontroller uinavigationcontroller

我可能对使用UINavigationControllerDelegate协议有一些误解。这是我的情况:

我有一个ViewController,让我们调用它,BViewController可以显示一个PopoverViewController。在AViewController之后,BViewController是NavigationContoller堆栈中的第二个ViewController。当用户点击BViewController中的按钮时,我需要关闭PopoverViewController,然后应用程序将我们带回到前一个视图 - AViewController。

为此,我在BViewController中实现了以下内容

- (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中,因此框架不会直接调用它。因此,我使用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参数都是即将显示的参数。我原以为第二种方法可以让我访问即将消失的那种方法。因此,当用户点击上述按钮时,将在AViewController(即将显示)上调用WillDisappear,而不是在BViewController(即将消失)上调用。听起来不错吗?苹果文档在两种情况下均指

  

正在显示其视图和导航项属性的视图控制器。

......我认为这不太清楚。谢谢你的帮助,伙计们。

2 个答案:

答案 0 :(得分:2)

两个委托方法都被调用相同的操作(显示视图控制器)。 navigationController: willShowViewController:animated:在之前被称为,新的视图控制器在gui中可见。在显示新的视图控制器后调用navigationController:navigationController didShowViewController:animated:

你会在很多来自apple的委托协议中找到这种模式。遗憾的是,您在NavigationViewController中没有委托方法,该方法告诉您该操作是弹出还是推送。

答案 1 :(得分:0)

我挂钩了我自己的协议,它将了解TO和FROM方面:

NavigationControllerDelegate.h:

@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;
}

在我的app委托中,我创建了其中一个对象并将其设置为导航控制器的委托:

...
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