Storyboardを使わずにコードのみで、TabやNavigationを実装する方法を紹介していきます。
コードのみでアプリケーションを作る際にすぐにコーディングできるように、この方法を覚えておくと便利だと思います。
実際にコードを実行するとこんな感じになります。
(ホームの画面)

(お問い合わせの画面)

(設定の画面)

この画面をコードのみで実装していきます。
ディレクトリ構成、処理の流れ
まずは、アプリプロジェクトのディレクトリ構成を説明します。
別にこのやり方に従う必要は全くなのですが、私の場合はこんな感じになっています。
Viewフォルダ
・ TextView.swift
Modelフォルダ(今回は何もありません)
Controllerフォルダ
・HomeViewController.swift
・ContactViewController.swift
・SettingViewController.swift
・MainTabBarController.swift
・MainNavigationController.swift
その他ファイル(AppDelegate.swiftなど)
そして、
アプリの全体的な処理の流れは
AppDelegate
→ MainTabBarController でタブを制御
→ 3つのMainNavigationControllerでナビゲーションを制御
→Home, Contact, SettingViewControllerそれぞれがTextViewを描写する。
という感じになっています。
実装したサンプルコード
実装したコードは以下のようになっています。
AppDelegate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var window: UIWindow? private(set) lazy var viewController = MainTabBarController() internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. // アプリウィンドウを設定します。 self.window = UIWindow(frame: UIScreen.main.bounds) // ウィンドウをヴィジブルにします。 self.window?.makeKeyAndVisible() // ウィンドウの rootViewController を viewController に設定します。 self.window?.rootViewController = viewController return true } |
AppDelegate.swiftは、新しいメンバ変数の追加とapplication()メソッドを変更します。
MainTabBarController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import UIKit class MainTabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() // 背景色 tabBar.barTintColor = UIColor.black // アイテムの色 tabBar.tintColor = UIColor.white let firstViewController = MainNavigationController(rootViewController: HomeViewController()) firstViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .bookmarks, tag: 0) let secondViewController = MainNavigationController(rootViewController: ContactViewController()) secondViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 1) let thirdViewController = MainNavigationController(rootViewController: SettingViewController()) thirdViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .more, tag: 2) self.viewControllers = [firstViewController, secondViewController, thirdViewController] } } |
背景色やアイテムの色を設定したあと、
first, second, thirdViewControllerにMainNavigationControllerのインスタンスを代入していき、
それらをself.viewControllersに配列として代入することでタブバーを実現しています。
また、タブバーのアイコンを変えるにはUITabBarItem.SystemItemを変更します。
とても簡単に変更できるので、詳しくはこれを読んでみてください。
https://developer.apple.com/documentation/uikit/uitabbaritem/systemitem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import UIKit class MainNavigationController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() // 背景色 navigationBar.barTintColor = UIColor.black // アイテムの色 navigationBar.tintColor = UIColor.white // テキスト navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
UINavigationControllerを継承したあと
背景色やアイテム(戻るボダんなど)、テキストの色を設定します。
こうすることによって
設定済みのMainNavigationControllerのインスタンスを使えば、UINavigationControllerのインスタンスを生成してから設定するよりも効率が良くなりメンテナンスも簡単になります。
Home, Contact, SettingViewController
1. HomeViewController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import UIKit class HomeViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.title = "ホーム" let mainView = TextView(frame: self.view.bounds, text: "ホーム") mainView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.view.addSubview(mainView) } } |
2. ContactViewController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import UIKit class ContactViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.title = "お問い合わせ" let mainView = TextView(frame: self.view.bounds, text: "お問い合わせ") mainView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.view.addSubview(mainView) } } |
3. SettingViewController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import UIKit class SettingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.title = "設定" let mainView = TextView(frame: self.view.bounds, text: "設定") mainView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.view.addSubview(mainView) } } |
これらのViewControllerは実際のアプリ画面を描写するために必要なのですが
ポイントはViewControllerとViewを分けていて、
ホーム、お問い合わせ、設定のViewControllerそれぞれがTextViewという一つのViewを再利用しているところです。
こうすることで同じコードを3回書く必要がなく
開発規模が大きくなっても後から困ることがありませんし、メンテナンス性も高くなります。
TextView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
class TextView: UIView { let mainLabel: UILabel init(frame: CGRect, text: String) { self.mainLabel = UILabel() self.mainLabel.text = text // 表示テキストのセンタリング self.mainLabel.textAlignment = .center // 親クラスを初期化 super.init(frame: frame) self.backgroundColor = .white self.addSubview(mainLabel) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() let labelSize = self.mainLabel.sizeThatFits(self.bounds.size) let x = (self.bounds.width - labelSize.width) / 2 let y = (self.bounds.height - labelSize.height) / 2 let labelOrigin = CGPoint(x: x, y: y) self.mainLabel.frame = CGRect(origin: labelOrigin, size: labelSize) } } |
TextViewはイニシャライズで引数を二つとるのですが、
一つ目はViewのサイズを決めるframeと、二つ目は画面に描写する文字を指定するtextです。
例えばtextにHello worldという文字列を渡せば、画面に「Hello world」と表示されますし
ViewControllerでのインスタンス生成時にホーム、お問い合わせ、設定など、好きな文字列を渡して表示させることができます。
ステータスバーの色を変更する方法
ステータスバーの文字色を白くするには
この記事に詳しく書いてあるので、こちらの方を読んでみてください。
http://progra.blog.jp/archives/5583495.html