Кнопка контроллера Popover контроллера iOS UISplitViewController исчезает после нажатия нового контроллера представления в портретном режиме - PullRequest
7 голосов
/ 25 октября 2011

В моем приложении UISplitViewController у меня есть

  • RootViewController - просмотр контроллера на левой панели.
  • DetailViewController - просмотр контроллера на правой панели.

При касании одного элемента (который находится в UITableView) в RootViewController будет установлен новый контроллер представления, как показано ниже:

[detailViewController setViewControllers:[NSArray arrayWithObjects:newViewController, nil] animated:animated];

//detailPane is my DetailViewController

Все работает довольно хорошо в ландшафтном режиме.Тем не менее, я не могу заставить UISplitViewController работать так, как мне нужно, в портретном режиме, то есть всплывающая кнопка RootViewController не отображается надлежащим образом в моем DetailViewController, когда я запускаю и использую приложение в режиме переноса.

КогдаЯ запускаю приложение в портретном режиме, кнопка всплывающего окна появляется соответственно.Но после нажатия одного элемента во всплывающем окне и установки нового контроллера представления на detailViewController кнопка исчезла.Мне нужно повернуть устройство в альбомную ориентацию, а затем снова в книжную ориентацию, чтобы кнопка снова появилась.

Я установил делегата моего UISplitViewController в AppDelegate моего приложения следующим образом:

self.splitViewController.delegate = self.detailViewController

А вот моя реализация UISplitViewControllerDelegate

- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem  forPopoverController: (UIPopoverController*)pc {
    NSLog(@"Will hide view controller");
    barButtonItem.title = @"Menu";
    [self.navigationItem setLeftBarButtonItem:barButtonItem];
    self.popoverController = pc;
}

- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
    NSLog(@"Will show view controller")
    NSMutableArray *items = [self.navigationItem.leftBarButtonItems mutableCopy];
    [items removeAllObjects];
    [self.navigationItem setLeftBarButtonItems:items animated:YES];
    [items release];
    self.popoverController = nil;   
}

Любая подсказка или помощь очень ценится.Спасибо.

Ответы [ 4 ]

4 голосов
/ 22 мая 2012

Только что придумал новое решение.

Подкласс UINavigationController и реализация UISplitViewControllerDelegate. Установите экземпляр этого класса в качестве правого ViewController для splitViewController. Каждый раз, когда вы хотите изменить контроллер подробного вида с главного

NewDetailViewController *newDetailVC = ....// Obtain the new detail VC

newDetailVC.navigationItem.leftBarButtonItem = [[[[self.splitViewController.viewControllers objectAtIndex:1]topViewController]navigationItem ]leftBarButtonItem];  //With this you tet a pointer to the button from the first detail VC but from the new detail VC

[[self.navigationController.splitViewController.viewControllers objectAtIndex:1]setViewControllers:[NSArray arrayWithObject:newDetailVC]];  //Now you set the new detail VC as the only VC in the array of VCs of the subclassed navigation controller which is the right VC of the split view Controller

Это работает для меня, и я могу избежать определения дырочного протокола и установки мастера в качестве делегата, что является большим компромиссом. Надеюсь, это поможет.

3 голосов
/ 15 ноября 2011

Если вам все еще нужно это:

http://developer.apple.com/library/ios/#samplecode/MultipleDetailViews/Introduction/Intro.html

Что я сделал с моим источником (у меня были с вами аналогичные настройки), чтобы исправить это:

У меня естьглавный viewcontroller (в моем случае UITableViewController) является делегатом UISplitViewController.В двух методах делегата для UISplitViewControllers (так будет в вашей основной реализации viewcontroller) вы сохраните popupviewcontroller и barbuttonitem в своем классе.Теперь, если вы измените ваш viewcontroller с деталями, вы выполните:

self.viewControllers = [NSArray arrayWithObjects:[self.viewControllers objectAtIndex:0], newDetailsViewController, nil];

UIViewController <SubstitutableDetailViewController>*vc = (UIViewController <SubstitutableDetailViewController>*)newDetailsViewController;

[vc invalidateRootPopoverButtonItem:_tableViewController.rootPopoverButtonItem];
[_createReportViewController showRootPopoverButtonItem:_tableViewController.rootPopoverButtonItem];

, где у нас есть

@protocol SubstitutableDetailViewController
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
@end

делегат, которого должен придерживаться каждый из ваших detailsViewControllers.Вы бы реализовали так:

- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
    self.navigationItem.leftBarButtonItem = barButtonItem;
}

- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
    self.navigationItem.leftBarButtonItem = nil;
}

Дайте мне знать, если это вам поможет.

2 голосов
/ 30 апреля 2013

Мне понравилось решение Nekto, но оно пропускает одну ключевую проблему.

Не ясно, какой селектор action: приведет к тому, что UISplitViewController отобразит MasterViewController во всплывающем окне. Когда я наконец понял это, изучив BarButtonItem в отладчике, я понял, почему так сложно это выяснить: селектор action: не документирован нигде в iOS SDK от Apple. К сожалению.

Попробуйте это:

UIBarButtonItem *showListView = [[UIBarButtonItem alloc] initWithTitle:@"List" style:UIBarButtonItemStyleBordered target:[self splitViewController] action:@selector(toggleMasterVisible:)];
[[detailViewController navigationItem] setLeftBarButtonItem:showListView];        

Возможно, вы захотите окружить этот код условием, которое проверяет, находится ли окно в портретном режиме, например if ([self interfaceOrientation] == UIInterfaceOrientationPortrait)

0 голосов
/ 26 октября 2011

Когда вы устанавливаете новые контроллеры представления, размещенные на navigation stack, возможно, все кнопки навигации сбрасываются. Вы можете вручную добавить соответствующие кнопки после изменения navigation stack.

Например, вы можете выбрать код из - (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc, где создана кнопка контроллера поповера по умолчанию:

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"Menu" style:UIBarButtonItemStyleBordered target:self action:@selector(appropriateSelector)];
[self.navigationItem setLeftBarButtonItem:barButtonItem];
self.popoverController = pc;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...