【Swift】TabBarをStoryboardReferenceでつなげて、なおかつNavigationControllerも使う方法


調べると載っている・・・けどなんかうまくいかない

あれもこれも機能を付けたい、でもできるだけすっきりとしたStoryboardで作りたいと思って調べたとき、結構つまずいたのでここに残しておきます。
これを読んでくれたあなたの助けになれば幸いです。
※できるだけ初心者向けに詳しく書いていくつもりです。

TabBarはStoryboardReferenceを使ってすっきり表示させる

そもそも理想はワンStoryboardワンViewControllerって言う割に、複数のStoryboardをつなげる事が必要なTabBar。
全部コードで書く方は別ですが、初心者にはStoryboardがごちゃごちゃになってしまう危険があります。
そこで登場するのがStoryboardReference。
StoryboardをReference(参照)することができる機能で、表示が小さいため、画面がすっきりします。

蛇足話ですが、僕が本当にxcodeで作り始めた頃、一つのStoryboardに全部のViewControllerを詰め込んだら重たくなりすぎて、うまく動作できなくなってしまいました。

やり方

1.StoryboardとViewControllerの準備

まず初めに、xcodeから新しいプロジェクトを作成し、シンプルなAppを選んでください。
ここではProdactNameをTabTestとしておきます。(名前はなんでもいいですよ)
InterfaceはStoryboardにしてください。SwiftUIは知りません。(勉強中)


(名前が恥ずかしいので隠してます)

次に、最初からあるMain.Storyboardは置いておいて、切り替えを行いたいStoryboardを2つ作成します。
Command + N を押すとすぐにnewfileが作れますよ;)
ここではFirstとSecondeと言う名前のStoryboardを作りました。
この二つはまだ空っぽの状態なので、右上の【+】を押して【View Controller】をドラッグドロップしましょう。

続いて、このView Controlerの中身を書くために、またNewFileを作ります。
今度は「Swift File」を選んでください。「cocoa touch class」の方が楽ですが、一つでもコードの記述に慣れるためにこちらを選んでいます。定文なのですぐ覚えれますよ;)
名前はStoryboardに合わせてFirstViewControllerとSecondViewControllerにします。
こんな感じになったと思います。

2.ViewControllerにコードを書く

それでは早速コードを書いていきましょう。
まず最初に記入されているimport Foundationは消してください。
んで、下記のコードを、日常の挨拶「おはよう」位の定型文として覚えてください。

FirstViewController.swift
import UIKit

class FirstViewController: UIViewController {
    override func viewDidLoad() {
    }
}

これは先ほどnewfileを作る時、「cocoa touch class」を選んでいれば自動で記載されている部分です。でも自分で書く事によって、今後に良い影響があると僕は思っています。(少なくとも僕はextension作成に抵抗が無くなったり?同じViewControllerファイル内に別classを書いたりする時に心理的に楽になりました。)

話が逸れました。

簡単に説明すると、まずUIKitと言ういろいろ便利なツール(道具)が入ったキット(道具箱)をimport(読み込み)ます。
次にファイルと同じ名前のクラスを作成することで可読性を高めます。また、このクラスはUIViewControllerとして機能しているクラスと設定しています。
viewDidLoad()部分は最初から「override...」と書き始めるより、「viewd...」くらい書くとxcodeの補填機能が働いて簡単に書けますよ。
このviewDidLoad()は、画面が表示された1回目のみ読み込まれる関数で、いろいろ初期設定をしたりすることが多いです。
super.viewDidLoad()は・・・superです。

3.storyboardに作成したclassを設定する

頑張って書いたclassをstoryboardに置いたViewControllerに設定します。

ViewControllerの上にあるバーをクリックすると、右側に詳細画面のようなものが見れるようになります。
この中のCustom classに先ほど作成したFirstViewControllerを設定しましょう。
Secondに関しても同じように設定します。

こうすることでコードが紐付き、プログラムが反映されることになります。

さらに、下の図の通りにボタンを押して【Is Initial View Controller】を有効にしておいてください。さらりと書いてますが必須です。

4.TabBarControllerを設置

放置していたMain.storyboardをここで使います。(慣れれば新しくTabBar.storyboardとか作るといいです)
図の順番に押していくと、今あるViewControllerにTabBarが設置できます。

左側がTabBarController、右側がViewControllerですが、右側はいらないのでdeleteで消してください。
TabBarだけが残ります。

5.Storyboard Referenceの設置と接続

右上の【+】を押して、Storyboard Referenceをドラッグドロップします。

マウスをTabBarControllerの上に持っていき、controlを押しながらクリックしっぱなしで、Storyboard Referenceまで持っていくとつなげることができます。
ここでつなげ方の種類に選択肢が出てきますが、【Relationship segue】というのを選んでください。

これをもう一度繰り返し、Storyboard Referenceを2つ繋げます。

6.Storyboard ReferenceとStoryboardを紐づける

Storyboard Referenceをクリックすると右側の詳細に図のような項目が現れます。
一番上のstoryboardのプルダウンに作成したFirstとSecondがあるので、それぞれ設定します。

これでTabBarがそれぞれのStoryboardに繋がりました。
一度Runしてみてエラーがないか見てみるのもいいでしょう。

7.それぞれのstoryboardにtabItemの設定をする

Runした素直な方はわかると思いますが、画面は真っ白です。
下部にほんのわずかに色づいたbarが見えますが、Itemが何も表示されていません。
それぞれのstoryboardにBarItemをおいていきましょう。
First.storyboardに【+】から【Tab Bar Item】をドラッグドロップします。下部に勝手に設置されるので、クリックしてみると、右側の詳細にtitleやimageといった項目が出てきます。適当に入力してみてください。imageはxcodeで用意してくれているものがたくさんあるので、適当に選びます。

secondも設定できたら、もう一度Runしてみてください。
見事Tabbarが設定され、切り替えができています。(どっちを押しても真っ白?そりゃどっちのViewControllerも真っ白い画面だからね;)

8.NavigationControllerの設置

ここまできたらゴールは目の前です。もう少し頑張って!
Main.storyboardに戻り、Storyboard Referenceをクリックします。先ほどTabBarControllerをくっつけたEmbed Inの中にNavigation Controllerがあったのを覚えていますか?
それぞれのStoryboard ReferenceにNavigation Controllerをつなげてください。
突然大きなNavigationControllerが出てきてびっくりしますが、大丈夫です。

9.NavigationControllerの設定

ほとんどコードを書いていないので、最後はコードをカッコよく書きましょう。

FirstViewController.swift
import UIKit

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setNavigation()
    }

    private func setNavigation(){
        navigationItem.title = "First"
    }
}
SecondViewController.swift
import UIKit

class SecondViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setNavigation()
    }

    private func setNavigation(){
        navigationItem.title = "Second"
    }
}

viewDidLoad()内にsetNavigation()という関数を呼び出します。
こうすることで、viewDidLoadでは何をしているのか、呼び出した先は何をしているのかがわかりやすくなります。
privateとかはググってくださいな。

これでRunしてみてください。画面の上部にFirst、Secondと表示されました!

おめでとうございます!よくがんばりました!私が3日間探してたどり着いた事に、あなたは数分でたどり着けましたね!!

終わりに

この記事の大半を深夜3時とかに書いていた為か、変なテンションになりました。
海外のHowTo記事とか見てるとこんな感じで励ましたり、まるで対話してるかのような書き方をしている事が多いので、そんな感じで書いてみました。
スクショも大量に載せたので正直めんd・・・記事が長くなってしまいましたね。

私もまだまだ初心者を抜け出せないので、間違いやもっといい方法があればご教授いただけると大好きになります。

冒頭にも書きましたが、この記事が誰かの手助けになれば幸いです。

Coding with me!;)