实现UINavigationControllerDelegate时出现问题

问题描述 投票:0回答:2

我可能对使用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(即将消失)上调用。 听起来不错吗? 苹果文档在两种情况下都指的是

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

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

ipad uiviewcontroller uinavigationcontroller
2个回答
2
投票

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

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


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
© www.soinside.com 2019 - 2024. All rights reserved.