Master-Detail template で tabBarController を追加する方法 (4)
このネタで 4 回も書くとは思ってもいなかったのですが、より良い方法があったので、後学のため書いておこうと。
Master-Detail template に tabBarController を追加するのにどこに追加するのか?という問題があり、さらに、いい加減に追加しても、error になりまくるので萎えてしまうという悪循環。結局のところ、こうするのが一番だということがわかりました。
- Xcode で、Master-Detail template を選択。storyboard は自動的に作られているので、table view controller を選択し、メニューから Editor > embed in > Tab Bar Controller を選択すると、tabBarController が追加されます。storyboard はどうなっているかというと、split view controller - navigation controller - tab bar controller - table view とつながっています。また、detail では navigation が表示されています。繋ぎ方を間違えると、split view controller - master からの遷移では navigation が表示されず、detail からは表示されるという妙な状況に。どちらからも navigation が表示されることを確認します。
- tab bar controller を embed in した状態で、試しに build & run してみると error になります。原因は、AppDelegate.m に追加した tabBarController の記述が無いためです。error を回避するため、AppDelegate.m を次のように変更します:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;
splitViewController.delegate = self;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
// MasterViewController *controller = (MasterViewController *)masterNavigationController.topViewController;
UITabBarController* tabBarController = masterNavigationController.tabBarController.viewControllers[0];
MasterViewController *controller = (MasterViewController *)tabBarController.viewControllers[0];
controller.managedObjectContext = self.persistentContainer.viewContext;
return YES;
}
- 次に、この状態で試しに build & run してみると相変わらず error になります。かなり萎えます。原因は、MasterViewController.m で、managedObjectContext について教えてあげる必要があるためです。また、build & run に成功しても、navigation が表示されないため、navigation について考慮した記載にします。MasterViewController.m を次のように変更します:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.tabBarController.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
self.tabBarController.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.persistentContainer.viewContext;
}
これで error にならず navigation も表示されるようになります。
tab をもう一枚追加するにはどうするのかとか、iPad で検証すると error になりそうな予感がしますが、躓くまでこれで進めてみることにしよう。