Проблема с реализацией UINavigationControllerDelegate - PullRequest
0 голосов
/ 03 марта 2011

У меня может быть некоторое недопонимание относительно использования протокола UINavigationControllerDelegate.Вот моя ситуация:

У меня есть ViewController, назовем его BViewController, который может отображать PopoverViewController.BViewController является вторым ViewController в стеке NavigationContoller после AViewController.Мне нужно отклонить PopoverViewController, когда пользователь нажимает кнопку в BViewController, и приложение возвращает нас к предыдущему представлению - 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.Следовательно, я регистрирую UINavigationControllerDelegate в своем NavigationController и реализую следующие два метода:

- (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 (который собирается исчезнуть).Это звучит правильно?В обоих случаях документация Apple ссылается на

Контроллер представления, для которого отображаются свойства вида и элементов навигации.

... что, я думаю, не совсем понятно,Спасибо за помощь, ребята.

Ответы [ 2 ]

2 голосов
/ 27 мая 2011

Оба метода делегата вызываются для одного и того же действия (показывает контроллер представления).navigationController: willShowViewController:animated: называется до , новый графический контроллер виден в графическом интерфейсе.navigationController:navigationController didShowViewController:animated: вызывается после показа нового контроллера представления.

Этот шаблон вы найдете во многих протоколах делегатов от Apple.К сожалению, у вас нет метода делегата в NavigationViewController, который бы сообщал вам, было ли действие всплывающим или принудительным.

0 голосов
/ 15 мая 2013

Я подключаю свой собственный протокол, который будет знать о сторонах 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;
}

В моем делегате приложения я создаю один из этих объектов и устанавливаю его в качестве делегата контроллера навигации:

...
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...