Master-Detail template で tabBarController を追加する方法 (4)

このネタで 4 回も書くとは思ってもいなかったのですが、より良い方法があったので、後学のため書いておこうと。

Master-Detail template に tabBarController を追加するのにどこに追加するのか?という問題があり、さらに、いい加減に追加しても、error になりまくるので萎えてしまうという悪循環。結局のところ、こうするのが一番だということがわかりました。

  1. 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 が表示されることを確認します。
  2. 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;

    }

  3. 次に、この状態で試しに 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 になりそうな予感がしますが、躓くまでこれで進めてみることにしよう。