IOS 8では、ViewControllerがshowDetailViewController:sender:
を呼び出して、詳細ViewControllerを表示するための適切なViewControllerをシステムに決定させることができるようになりました。
私のアプリには、viewControllers配列に2つのUINavigationControllersを含むUISplitViewControllerがあります。最初のUINavigationControllerには、UITableViewControllerのサブクラスである「マスター」ビューが含まれています。 2番目のUINavigationControllerには、「詳細」ビューが含まれています。
私はこれを普遍的に機能させようとしているので、showDetailViewController:sender:
を使用して詳細ビューを表示しようとしています。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.itemVC.item = self.itemStore.items[indexPath.row];
[self showDetailViewController:self.itemVC sender:self];
}
これは、self.splitViewController.collapsed == YES
の場合、Horizontal Compactトレイト(iPhoneスタイル)では正常に機能しますが、トレイトが通常(iPad、折りたたまれていない)の場合は機能しません。 iPadでは、詳細UINavigationControllerを(そのUINavigationControllerのviewControllers配列を置き換える代わりに)ベア詳細ビューコントローラーに置き換えます。
これを回避するために、折りたたまれているかどうかをテストします。折りたたまれていない場合は、詳細ビューコントローラーを別の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];
}
}
しかし、これは、self
とビュー階層の残りの部分との間の結合を緩めるというshowDetailViewController:sender:
の目的を無効にしているように感じます。
これを処理するためのより良い方法はありますか?
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];
}
これで問題が解決することを願っています。
あなたがそれをする方法には問題があります。選択後にデバイスを回転させる(モードを折りたたみからallVisibleに変更する)と、ナビゲーションコントローラーのない詳細vcが表示されます。
すべての場合にshowDetailViewController:sender:
を呼び出し、ナビゲーションコントローラーを使用してView Controllerを渡すと、どちらの場合も正常に機能し、上記の回転の問題も修正されます。
- (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];
}