公開中のアプリ

[Swift/Xcode]初心者必見!iOSアプリ作成から公開まで徹底解説!#07 「ナビゲーションコントローラーをコードで実装編」

ラベルとナビゲーションコントローラーの実装をしようと思いましたが
長くなっちゃいそうなので今回はナビゲーションコントローラーだけ
実装したいと思います。

デザインはまだ決まっていないのでとりあえず簡単に実装するだけにしたいと思います。

動作環境は下記の通りです!
Xcode Version 12.5 Swift version 5.4

MainViewController.swiftを作成

ではナビゲーションコントローラーをコードで実装したいと思います!

今回は新たにMainViewController.swiftと言うファイルを作成して
そこに今までコードを書いてきたViewController.swiftの内容をコピペします。

新しいファイルの作り方は下記画像を参考にして下さい。

これでファイルが作れたと思います。

ViewController.swiftの内容を作ったMainViewController.swiftにコピペして下さい。
下記のようになっていればOKです!
3行目と90行目のViewControllerをMainViewControllerに変更してます。

import UIKit
 
class MainViewController: UIViewController {
 
    //スクロールビュー
    let scrollView = UIScrollView()
    //ボタンを表示用のビュー
    let inView: UIView = UIView()
    //スタックビュー縦用
    var stackV: UIStackView = UIStackView()
    //ボタンの配列
    var buttonArray: [UIButton] = []
    //スタックビュー横を格納する為の配列
    var stkArray: [UIStackView] = []
    //貯金額合計
    var totalSavings = 0
    //貯金開始?日目
    var whatDay = 0
 
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //ビューの生成
        viewCreate()
        //ボタンの生成
        btnCreate()
        //スタックビューの生成
        stackViewCreate()
    }
    
    //ビュー生成
    func viewCreate() {
        //スクロールビューの表示
        view.addSubview(scrollView)
        //ボタン表示用ビューの表示
        scrollView.addSubview(inView)
        
        //スクロールビューの設定
        //AutosizingをAutoLayoutに変換しないようにしている(おまじない)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        //X軸
        scrollView.centerXAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerXAnchor).isActive = true
        //Y軸
        scrollView.centerYAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerYAnchor).isActive = true
        //横幅
        scrollView.widthAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.9).isActive = true
        //縦幅
        scrollView.heightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.9).isActive = true
 
        //ボタン表示用ビューの設定
        //AutosizingをAutoLayoutに変換しないようにしている(おまじない)
        inView.translatesAutoresizingMaskIntoConstraints = false
        //横幅
        inView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 1.0).isActive = true
        //この4つの制約をつけて初めてスクロールするっぽい
        inView.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
        inView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0.0).isActive = true
        inView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0.0).isActive = true
        inView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0.0).isActive = true
    }
    
    //ボタン生成
    func btnCreate() {
        //ボタンの生成と設定
        //ボタンにtagを付ける為の変数
        var tagNumber = 1
        //for文でボタンを生成
        for _ in 0...364 {
            //ボタン生成
            let button: UIButton = UIButton(type: .custom)
            //タイトルの色
            button.setTitleColor(UIColor.black, for: UIControl.State())
            //タイトルは数字なのでtagナンバーを指定
            button.setTitle(String(tagNumber), for: UIControl.State())
            //tag設定
            button.tag = tagNumber
            //背景色
            button.backgroundColor = UIColor.lightGray
            //ボーダーの横幅
            button.layer.borderWidth = 3
            //ボターの色
            button.layer.borderColor = UIColor.black.cgColor
            //AutosizingをAutoLayoutに変換しないようにしている(おまじない)
            button.translatesAutoresizingMaskIntoConstraints = false
            //ボタンの横幅が可変なのでボタンの高さは横幅と同じ長さを指定する事で正方形にしてる。
            button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1.0).isActive = true
            //変数tagNumberに1追加
            tagNumber += 1
            // タップされたときのaction
            button.addTarget(self, action: #selector(MainViewController.buttonTapped(_:)), for: .touchUpInside)
            //ボタンの配列に追加
            buttonArray.append(button)
        }
    }
    
    //365ボタンをタップした時の処理
    @objc func buttonTapped(_ sender : UIButton) {
        
        totalSavings += sender.tag
        whatDay += 1
        print("貯金開始\(whatDay)日目 貯金額\(totalSavings)円")
        buttonArray[sender.tag - 1].backgroundColor = UIColor.red
    }
    
    //スタックビュー生成
    func stackViewCreate() {
        //スタックビュー縦の設定
        //スタックビューの方向を縦に
        stackV.axis = .vertical
        //中のオブジェクトをどこに揃えて配置するか
        stackV.alignment = .fill
        //どう配置するか
        stackV.distribution = .fill
        //オブジェクト同士のスペース
        stackV.spacing = 4
        //おまじない
        stackV.translatesAutoresizingMaskIntoConstraints = false
        //stackVの背景色
        stackV.backgroundColor = UIColor.white
        //stackVを表示
        inView.addSubview(stackV)
        //X軸
        stackV.centerXAnchor.constraint(equalTo: inView.centerXAnchor).isActive = true
        //トップ位置
        stackV.topAnchor.constraint(equalTo: stackV.topAnchor, constant: 0.0).isActive = true
        //横幅
        stackV.widthAnchor.constraint(equalTo: inView.widthAnchor, multiplier: 1.0).isActive = true
        //縦幅
        stackV.heightAnchor.constraint(equalTo: inView.heightAnchor, multiplier: 1.0).isActive = true
 
        //スタックビュー横を自動生成
        for i in 0 ..< 73 {
            //StackHの生成
            let stackH:UIStackView = UIStackView()
            //スタックビューの方向を横に
            stackH.axis = .horizontal
            //オブジェクト同士のスペース
            stackH.spacing = 4
            //中のオブジェクトをどこに揃えて配置するか
            stackH.alignment = .fill
            //どう配置するか
            stackH.distribution = .fillEqually
            //スタックビュー配列に追加
            stkArray.append(stackH)
            //stackVの中にstackHを格納
            stackV.addArrangedSubview(stkArray[i])
        }
 
        //ボタンの配置
        //for文のカウンター変数
        var count = 0
        //for文で365個のボタンをどのstackHに入れるか決めている
        for i in 1 ..< 366 {
            //カウントの数に応じてどのstackHに入るか決定する。
            stkArray[count].addArrangedSubview(buttonArray[i - 1] as UIView)
            //ボタンは5列なので5の倍数でcountを一つ増やす。
            if i % 5 == 0 {
                count += 1
            }
        }
    }
}

ViewController.swiftの修正

そしてViewController.swiftはナビゲーションコントローラーにしちゃいます!
しちゃいますって言う表現は正しいかどうか分かりませんが(^^;

下記コードに書き換えましょう!

import UIKit

class ViewController: UINavigationController {
    //ストーリーボードからこれが呼ばれる
    required init?(coder aDecoder: NSCoder) {
        super.init(rootViewController: MainViewController())
    }
}

ここのコードですが、調べたサイトに詳しい事が書いてなかったので
ちょっと憶測になっちゃうんですけど、、、
(本当は詳しく調べた方が良いと思うんですけど一旦スルーしますw)

3行目がUINavigationControllerに書き換わってるので
ここでナビゲーションコントローラーになってると思います。

6行目rootViewController: MainViewController()のところで最初に表示される
ビューコントローラーをさっき作成したMainViewControllerに指定してる感じだと思います。

次にAppDelegate.swiftにもコードを書き加えます。

AppDelegate.swiftの修正

import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
     
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = UINavigationController(rootViewController: MainViewController())
        //ナビゲーションバーの色がデフォルトだと半透明になってしまうので、半透明にさせないよう設定
        UINavigationBar.appearance().isTranslucent = false
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
}

5行目と10行目〜13行目が追加したコードです!
Xcodeのバージョンによってはデフォルトで書かれてるコードが若干違うかもしれません。

これでナビゲーションコントローラーの設置は完了です!

一回ビルドして確認したいと思いますが、わかりやすいようにMainViewController.swiftのviewDidLoad()の中に下記コードを追加して下さい!

//タイトル設定
self.title = "365貯金"
//背景が黒くならないように設定
view.backgroundColor = UIColor.systemBackground

ビルドしたら下記画像のようになっていると思います。

まとめ

今回はナビーションコントローラーのみ実装しました!
ナビーションコントローラーにはボタンを設置する予定ですが、それはまた今度にします!

次回は貯金額とかを表示するラベルを実装したいと思います!

今回の企画もこれで7回になりました!
しかしあまり見てくれてる人がいない(T-T)

“[Swift/Xcode]初心者必見!iOSアプリ作成から公開まで徹底解説!#07 「ナビゲーションコントローラーをコードで実装編」” への3件のフィードバック

  1. […] ではメニュー画面用の新規ファイルを作成しておきましょう!Cocoa Touch ClassでSubclassをUIViewControllerにしてファイル名をMenuViewController.swiftにして下さい!わからない場合こちらの記事をご覧下さい〜作ったファイルではとりあえず背景色だけ変更しておきます! […]

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

アプリ