В UISplitViewController невозможно сделать showDetailViewController: отправитель: нажать на детальную навигациюController
В iOS 8 контроллеры представлений теперь могут вызывать showDetailViewController:sender:
, чтобы система определяла правильный контроллер представления, чтобы представить контроллер подробного представления.
В моем приложении у меня есть UISplitViewController, который содержит два UINavigationControllers в своем массиве viewControllers. Первый UINavigationController содержит мой "главный" вид, подкласс UITableViewController. Второй UINavigationController содержит мое представление "detail".
Поскольку я пытаюсь сделать эту работу универсально, я пытаюсь использовать showDetailViewController:sender:
для отображения подробного представления:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
[self showDetailViewController:self.itemVC sender:self];
}
Это отлично работает с характеристикой Horizontal Compact (стиль iPhone), когда self.splitViewController.collapsed == YES
, но не тогда, когда черта является регулярной (iPad не рушится). На iPad он заменяет деталь UINavigationController нечетным контроллером подробных представлений (вместо замены этого массива viewControllers UINavigationController).
Чтобы обойти это, я тестировался на то, рушился он или нет, и если это не так, я завершу контроллер подробного представления в другой UINavigationController, прежде чем показывать его:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
UIViewController *vcToShow;
// For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it.
if (self.splitViewController.collapsed) {
vcToShow = self.itemVC;
} else {
vcToShow = [[UINavigationController alloc] initWithRootViewController:self.itemVC];
}
[self showDetailViewController:vcToShow sender:self];
}
В качестве альтернативы я мог бы просто настроить self.itemVC
и вообще не называть showDetailViewController:sender:
при self.splitViewController.collapsed == NO
:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
// For whatever reason, when not collapsed, showDetailViewController replaces the detail view, doesn't push onto it.
if (self.splitViewController.collapsed) {
[self showDetailViewController:vcToShow sender:self];
}
}
Но это похоже на то, что он побеждает цель showDetailViewController:sender:
, которая должна ослабить связь между self
и остальной иерархией представлений.
Есть ли лучший способ справиться с этим?
Ответы
Ответ 1
В showDetailViewController:sender:
в зависимости от свойства collapse
вам нужно создать контроллер, который вы хотите показать в деталях.
например. На iPad в ландшафтном режиме он уже создаст контроллер подробного представления из раскадровки, но на iPhone 5, где он рухнул, контроллер просмотра еще не существует.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UINavigationController *detail;
ImageViewController *imageVC;
// on the iPhone (compact) the split view controller is collapsed
// therefore we need to create the navigation controller and its image view controllerfirst
if (self.splitViewController.collapsed) {
detail = [[UINavigationController alloc] init];
imageVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ImageViewController"];
[detail setViewControllers:@[imageVC] animated: NO];
}
// if the split view controller shows the detail view already there is no need to create the controllers
else {
id vc = self.splitViewController.viewControllers[1];
if ([vc isKindOfClass:[UINavigationController class]]) {
detail = (UINavigationController *)vc;
imageVC = [detail.viewControllers firstObject];
}
}
[self prepareImageViewController:imageVC forPhoto:self.photos[indexPath.row]];
// ask the split view controller to show the detail view
// the controller knows on iPhone and iPad how to show the detail
[self.splitViewController showDetailViewController:detail sender:self];
}
Надеюсь, это решит вашу проблему.
Ответ 2
То, как вы это делаете, имеет проблему. Если вы выберете устройство (измените режим с момента его сглаживания на allVisible) после выбора, вы найдете деталь vc без контроллера навигации.
Если вы вызываете showDetailViewController:sender:
во всех случаях и передаете контроллер вида с помощью навигационного контроллера, он будет работать нормально в обоих случаях, а также устранит проблему ротации, упомянутую выше.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
UIViewController *vcToShow= [[UINavigationController alloc] initWithRootViewController:self.itemVC];
[self showDetailViewController:vcToShow sender:self];
}
Ответ 3
if (self.splitViewController.collapsed)
[self.splitViewController showDetailViewController:self.itemVC sender:self];
else
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;