Open8

FlutterエンジニアのSwift勉強3 ~UIkit編~

heyhey1028heyhey1028

SwiftUI以前(iOS13未満)のエントリーポイント

SwiftUI以前ではUI生成に対してUI生成用のGUI「Storyboard」及びUIkitを使って開発が行われていました。その際、エントリーポイントに関してもSwiftUIとは異なる記述がなされていました。Flutterプロジェクト内に生成されるiOSのエントリーポイントはこちらのStoryboard+UIKit時代が使用されています。

Code

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Reference

https://swift-ios.keicode.com/ios/initialization-sequence.php

heyhey1028heyhey1028

Storyboard使ってみる

用語

View:UIコンポーネントの事。
ViewController:いわゆるMVCで言うところのViewController。Viewとビジネスロジックの橋渡し役。
Scene:ViewとViewControllerを含むアプリケーションの1画面の事。Storyboard上ではView Controller Sceneと表示。

手順

  1. Sceneに対してViewを追加

Tips

storyboardのソースコード
Storyboardを右クリック > open as > source codeでstoryboardのコードを見ることが出来る。いわゆるxmlファイルやhtmlファイルのような記述を見ることが出来る。

Reference

https://mo-gu-mo-gu.com/ios-storyboard-basic/

heyhey1028heyhey1028

画面遷移

UIKit x Storyboardでの開発では3つの画面遷移の実装方法があります。

  1. Segue(セグウェイ)
  2. UIViewControllerのpresentメソッド
  3. UINavigationControllerのpushViewControllerメソッド

Segueを使わない画面遷移

  1. StoryboardIDをつける
  2. 遷移元の画面でボタンと画面遷移を定義

Reference

https://swift-ios.keicode.com/ios/segue.php
https://faboplatform.github.io/SwiftDocs/1.uikit/015_uiviewcontroller/
https://qiita.com/misakiagata/items/b7f6c2f6c9f988ec38c7

heyhey1028heyhey1028

UIkitをコードで開発する

Viewコンポーネントの追加

  • 基本的に各ViewコンポーネントはViewControllerのviewDidLoadで追加していく
  • JavaのようにViewコンポーネントのクラスを作成し、それにアトリビュートを追加していくような形
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let addNumberButton = UIButton()
        addNumberButton.backgroundColor = UIColor.blue
        addNumberButton.setTitle("+", for: UIControl.State.normal)
        let viewWidth = self.view.frame.width
        let viewHeight = self.view.frame.height
        addNumberButton.frame = CGRect(x: viewWidth/2, y: viewHeight/2, width: 160, height: 80)
        addNumberButton.center = self.view.center
        addNumberButton.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
        self.view.addSubview(addNumberButton)

    }
}

Viewコンポーネントに対してイベントハンドラを紐づける

上記で作成したViewコンポーネントに対し、#selectorでメソッドを紐付けます。この際にViewコンポーネント側からメソッドを実行出来るようにメソッドには@objc属性を付与します。

    ...
    addNumberButton.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
    ...

    @objc func didTapButton() {
        let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
        self.present(secondViewController, animated: true, completion: nil)

    }

ViewControllerファイルの追加

Storyboardを使わずにViewControllerを追加するには、メニューからFile>New>File...と進み、「Cocoa Touch Class」を選択、次のダイアログでUIViewControllerのサブクラスとして作成します。

https://arc.net/l/quote/cqlnngul

heyhey1028heyhey1028

TabBarを追加する

Flutterで言うところのBottonNavigationBarのUIを実装してみます。

StoryboardでTab Bar Controllerを使う

最もシンプルにはStoryboardでTab Controllerを追加することでTabBarとその遷移先の画面を作る事が可能です。

Storyboardで作成したViewControllerをコード内で使う

もしStoryboardで先に作成したViewControllerをコード上のUITabBarControllerで使いたい場合は、storyboard.instantiateViewController(withIdentifier: [設定したstoryboardID名])でstoryboard上のviewControllerをインスタンス化し、UITabBarControllerのviewControllersの配列に追加します。

class MainTabControllerViewController: UITabBarController {

   override func viewDidLoad() {
       super.viewDidLoad()
       let storyboard = UIStoryboard(name: "Main", bundle: nil)
       let firstViewController = storyboard.instantiateViewController(withIdentifier: "TB-1")
       firstViewController.tabBarItem = UITabBarItem( tabBarSystemItem: .bookmarks, tag: 0)
       let secondViewController = storyboard.instantiateViewController(identifier: "TB-2")
       secondViewController.tabBarItem = UITabBarItem( tabBarSystemItem:.downloads, tag: 0)
       let thirdViewController = storyboard.instantiateViewController(identifier: "TB-3")
       thirdViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 0)
       viewControllers = [firstViewController,secondViewController,thirdViewController]
   }
}

TabBarの背景色を付ける

iOS15からUITabBarの背景が取り除かれた為、明示的に背景色を指定する必要がある

https://qiita.com/SaturnR7/items/b377f0b5bffa8264a5b4

Reference

https://qiita.com/oskmr/items/6b394481a930fefdea2c
https://dev.classmethod.jp/articles/uitabbar_and_uitabbarcontroller/

heyhey1028heyhey1028

UIKitでのUI開発

UIKitでUI開発を行う際にはいくつかのアプローチが存在する。これらが初見だと混在して、混乱する。また参考にできる記事もこれらが混在しているので、結構大変。

  1. StoryboardとSegueを使ったGUIベースでの開発
  2. StoryboardとXIBファイルを用いたGUIとコードを用いた開発
  3. コードのみを用いた開発

これは先の画面遷移を実現する方法にも通じる。Segueでの画面遷移もあればSegueとコードを併せた方法、コードのみで実現する方法が存在する。

XIBファイルを用いた開発

https://qiita.com/hiromasa-fun/items/d4d115a63939246ff3cc