Posiadanie UINavigationController w widoku głównym UISplitViewController w systemie iOS 8
W moim UISplitViewController, widok główny jest kontrolerem UINavigationController zawierającym Kontroler UITableViewController. Czasami, gdy użytkownik wybierze element w tabeli, muszę wypchnąć inny kontroler tableViewController nad istniejącą tabelę w widoku głównym.
W iOS 7, w moim pierwszym UITableViewController po prostu wywołuję
[self.navigationController pushViewController:otherTableVC animated:YES];
W iOS 8:
Gdy rozdzielony widok jest zwinięty, otherTableVC staje się widokiem szczegółów! Następnie po obróceniu urządzenia widzimy dwie tabele obok siebie...
Co gorsza, jeśli urządzenie pokazuje dwa panele, kod działa świetnie, a druga tabela jest przesuwana nad pierwszą w widoku głównym. Ale po podwójnym obrocie, dwa stoły są ponownie obok siebie. Wygląda na to, że zwinięty tryb UISplitViewController zakłóca mój własny Kontroler nawigacyjny...
Jak mogę zarządzać własnym kontrolerem UINavigationController w widoku głównym?
Dziękuję
EDITED:
Moje zarówno podstawowe jak i szczegóły widoki mają Kontroler nawigacji. Aby rozwiązać mój problem, odkryłem, że w trybie zwiniętym muszę stworzyć dodatkowy Kontroler nawigacyjny i przesunąć go nad głównym kontrolerem nawigacyjnym.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:otherTableVC];
[self.navigationController pushViewController:navController animated:YES];
Odkryłem, że możemy wcisnąć Kontroler nawigacyjny do innego kontrolera nawigacyjnego. 1 answers
Krótka odpowiedź, możesz kontrolować to zachowanie za pomocą metod UISplitViewControllerDelegate:
splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
splitViewController:separateSecondaryViewControllerFromPrimaryViewController:
Podejrzewam, że to, co naprawdę chcesz zrobić, to poradzić sobie z sytuacją, w której masz aplikację opartą na iOS 8 UISplitViewController, w której główne i szczegółowe widoki są zarówno UINavigationControllers, jak i istnieją pewne kontrolery viewControllers (w tych kontrolerach nawigacyjnych), które chcesz wyświetlać tylko po stronie głównej lub szczegółowej podzielonego widoku. Odpowiedź poniżej dotyczy tego. Informatyka radzi sobie również z sytuacją, w której czasami chcesz, aby Widok zastąpił widoki w kontrolerze nawigacji szczegółowej, a nie został tam pchnięty.
Małe zastrzeżenie: poniższy kod Nie dotyczy wszystkich możliwych przypadków i ma pewne założenia:
- nie spodziewamy się, że cokolwiek może się zmienić na stosie kontrolerów nawigacji szczegółowej, gdy rozdzielony Widok zostanie zwinięty, a widoki te zostaną zasłonięte przez szczegółowy widok nad nimi.
- nasze podklasy UIViewController wszystkie mają właściwość shouldDisplayInDetailedView i shouldReplaceDetailedView
- Zakładamy, że wypychamy widoki tylko do kontrolera nawigacji szczegółowej, który ma ustawioną właściwość shouldDisplayInDetailedView.
- Kontrolery widoku są dodawane do strony szczegółów poprzez splitViewController:showDetailViewController: lub pushViewController:animated: we właściwości navigationController widoku szczegółowego (w stanie rozwiniętym lub zwiniętym).
- Kontrolery widoku to powinno zastąpić Kontrolery widoku w kontrolerze nawigacyjnym Detail są dodawane tylko przez splitViewController: showDetailViewController: i tylko z interakcji z widokiem w głównym kontrolerze widoku, tzn. może się to zdarzyć tylko wtedy, gdy główny kontroler widoku nie jest zasłonięty, gdy jest w stanie zwiniętym.
- mamy BlankViewController do wyświetlenia w widoku szczegółów, gdy kontroler dzielonego widoku zostanie rozszerzony, ale mamy tylko Kontrolery widoku, które powinny pozostać na Strona główna.
Nie polecam implementacji tylko jednej strony splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: / splitViewController: separateSecondaryViewControllerFromprimaryviewcontroller: logiczne i w zależności od domyślnej implementacji dla drugiej strony. Apple robi dziwne rzeczy, takie jak umieszczenie kontrolera Uinavigationviewcontroller od strony szczegółów do strony głównej jako jednego z kontrolerów ViewController w głównym kontrolerze nawigacyjnym stos, ale potem wciskając nad nim inne kontrolery widoku, które nawet jeśli całkowicie rozumiesz, nadal nie mogą być replikowane z własnego kodu. Dlatego najlepiej jest samodzielnie obsługiwać obie strony procesu.
Tego używam:
#pragma mark -
#pragma mark Split View Controller delegate.
- (BOOL)splitViewController:(UISplitViewController *)splitViewController showViewController:(UIViewController *)vc sender:(id)sender
{
//Standard behaviour. This won't get called in our case when the split view is collapsed and the primary view controllers are obscured.
return NO;
}
// Since we treat warnings as errors, silence warning about unknown selector below on UIViewController subclasses.
#pragma GCC diagnostic ignored "-Wundeclared-selector"
- (BOOL)splitViewController:(UISplitViewController *)splitViewController showDetailViewController:(UIViewController *)vc sender:(id)sender
{
if (splitViewController.collapsed == NO)
{
// The navigation controller we'll be adding the view controller vc to.
UINavigationController *navController = splitViewController.viewControllers[1];
UIViewController *topDetailViewController = [navController.viewControllers lastObject];
if ([topDetailViewController isKindOfClass:[BlankViewController class]] ||
([vc respondsToSelector:@selector(shouldReplaceDetailedView)] && [vc performSelector:@selector(shouldReplaceDetailedView)]))
{
// Replace the (expanded) detail view with this new view controller.
[navController setViewControllers:@[vc] animated:NO];
}
else
{
// Otherwise, just push.
[navController pushViewController:vc animated:YES];
}
}
else
{
// Collapsed. Just push onto the conbined primary and detailed navigation controller.
UINavigationController *navController = splitViewController.viewControllers[0];
[navController pushViewController:vc animated:YES];
}
// We've handled this ourselves.
return YES;
}
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController
{
UINavigationController *primaryNavController = (UINavigationController *)primaryViewController;
UINavigationController *secondaryNavController = (UINavigationController *)secondaryViewController;
UIViewController *bottomSecondaryView = [secondaryNavController.viewControllers firstObject];
if ([bottomSecondaryView isKindOfClass:[BlankViewController class]])
{
NSAssert([secondaryNavController.viewControllers count] == 1, @"BlankViewController is not only detail view controller");
// If our secondary controller is blank, do the collapse ourself by doing nothing.
return YES;
}
// We need to shift these view controllers ourselves.
// This should be the primary views and then the detailed views on top.
// Otherwise the UISplitViewController does wacky things like embedding a UINavigationController inside another UINavigation Controller, which causes problems for us later.
NSMutableArray *newPrimaryViewControllers = [NSMutableArray arrayWithArray:primaryNavController.viewControllers];
[newPrimaryViewControllers addObjectsFromArray:secondaryNavController.viewControllers];
primaryNavController.viewControllers = newPrimaryViewControllers;
return YES;
}
- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController
{
UINavigationController *primaryNavController = (UINavigationController *)primaryViewController;
// Split up the combined primary and detail navigation controller in their component primary and detail view controller lists, but with same ordering.
NSMutableArray *newPrimaryViewControllers = [NSMutableArray array];
NSMutableArray *newDetailViewControllers = [NSMutableArray array];
for (UIViewController *controller in primaryNavController.viewControllers)
{
if ([controller respondsToSelector:@selector(shouldDisplayInDetailedView)] && [controller performSelector:@selector(shouldDisplayInDetailedView)])
{
[newDetailViewControllers addObject:controller];
}
else
{
[newPrimaryViewControllers addObject:controller];
}
}
if (newDetailViewControllers.count == 0)
{
// If there's no detailed views on the top of the navigation stack, return a blank view (in navigation controller) for detailed side.
UINavigationController *blankDetailNavController = [[UINavigationController alloc] initWithRootViewController:[[BlankViewController alloc] init]];
return blankDetailNavController;
}
// Set the new primary views.
primaryNavController.viewControllers = newPrimaryViewControllers;
// Return the new detail navigation controller and views.
UINavigationController *detailNavController = [[UINavigationController alloc] init];
detailNavController.viewControllers = newDetailViewControllers;
return detailNavController;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-08 08:54:00