🎃

UIKitを使った開発での最良の選択 ~View編~

2020/12/25に公開

はじめまして! チキングです!!
この記事はiOS #2 Advent Calendar 2020の23日目になります。
この記事は筆者の感覚によるものが多いので必ずしもこれが正解という訳ではないのでよろしくお願いします。

まず初めに

皆さんは普段の開発では、アプリケーションのViewの部分をなにを使って開発していますか?
良ければコメント欄を使って教えてください。

現在の主な環境

  • UIKit
    • storyboard
    • Xib
    • Codeを用いて作成
  • SwiftUI

になっています。
その中でも今回はUIKitに絞って書いていきます。
後日、改めてSwiftUIも絡めた比較もやる予定です。

それぞれの紹介

storyboard

どんなものか



Storyboardには複数の画面レイアウトと,それに加えて,画面と画面をどのように繋ぐかの画面遷移情報も含められます。

良いところ

  • デバイスごとのレイアウト・確認、画面遷移、デザインなどを直感的に設定できる。
    →プログラミング初心者にとってとっつき易いものである
  • iOS13からstoryboardでもititializerでのDIができるようになったところ
    →xibでできていたことがstoryboardでもできるようになったため、開発の敷居が下がりました。参考URL1

困りどころと解決策

  • iOSアプリケーションをチームで開発していた時に、1つのstoryboardに対して多数のViewControllerを置いて開発を進めるとコンフリクトが頻発する恐れがある。
    →1VCにつき1つのstoryboardを用意して開発していけば、コンフリクトは少なくなります。
  • storyboardの実態が特殊な記法のxmlであるためUI構築をしようと、安易な気持ちで編集してしまうとファイルを壊しかねないこと。
    → 触らずにGUIで編集していくのが一番かなって思います。
     コンフリクトが発生した際は別エディターで開いて解消してあげれば良いので大丈夫です。

Xib

どんなものか



xibファイルは,1画面分の画面レイアウト,または画面の一部のビューのみを表現するのに用いられる

良いところ

  • デバイスごとのレイアウト・確認、画面遷移、デザインなどを直感的に設定できる。
    →プログラミング初心者にとってとっつき易いものである
  • CustomViewが容易に作成できる。
  • UIをコンポーネント単位で切り出してViewの使い回しが容易になる

困りどころと解決策

  • コンポーネントを切る粒度が難しい
     →コンポーネント指向の本を読んだり、使い回さなかったらコンポーネントとして分けなくてもいいかなって思います。
  • CustomView作ったけど、ロードする時はどれを使えば良いの??
     →何度もインスタンス化するならUINibを使った方が良いみたい。
    UINibは裏でキャッシュを取っているみたいなので使いましょう。参考URL2

Codeを用いて作成

どんなものか

private lazy var emailContainerView: InputContainerView = {
        return InputContainerView(image: #imageLiteral(resourceName: "ic_mail_outline_white_2x"), textField: emailTextField)
    }()
class InputContainerView : UIView {

    init(image: UIImage, textField: UITextField) {
        super.init(frame: .zero)
        setHeight(height: 50)
        let iv = UIImageView()
        iv.image = image
        iv.tintColor = .white
        iv.alpha = 0.87
        addSubview(iv)
        iv.centerY(inView: self)
        iv.anchor(left: leftAnchor, paddingLeft: 8)
        iv.setDimensions(width: 24, height: 24)
        addSubview(textField)
        textField.centerY(inView: self)
        textField.anchor(left: iv.rightAnchor,
                         bottom: bottomAnchor,
                         right: rightAnchor,
                         paddingLeft: 8,
                         paddingBottom: -8)

        let dividerView = UIView()
        dividerView.backgroundColor = .white
        addSubview(dividerView)
        dividerView.anchor(left: leftAnchor,
                           bottom: bottomAnchor,
                           right: rightAnchor,
                           paddingLeft: 8,
                           height:0.75)

    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

良いところ

  • Codeで書ける!!
  • CustomViewが容易に作成できる。
  • UIをコンポーネント単位で切り出してViewの使い回しが容易になる
  • xmlを触らずに済む
  • コンフリクトしても容易に修正できる

困りどころと解決策

  • 逐一Viewを確認できない
     →Xcodepreviewを使えば解決参考URL3
  • AutoLayout周りで少し大変
     → Extentionsとかでまとめておけば使い回しができて少しは楽になる
    extension UIView {
        func anchor(top: NSLayoutYAxisAnchor? = nil,
                left: NSLayoutXAxisAnchor? = nil,
                bottom: NSLayoutYAxisAnchor? = nil,
                right: NSLayoutXAxisAnchor? = nil,
                paddingTop: CGFloat = 0,
                paddingLeft: CGFloat = 0,
                paddingBottom: CGFloat = 0,
                paddingRight: CGFloat = 0,
                width: CGFloat? = nil,
                height: CGFloat? = nil) {
        translatesAutoresizingMaskIntoConstraints = false
             ...以下略
         } 
     }
    
  • IB(Interface Builder)がないので全部自分でやる必要がある
     →まぁ勉強と思ってやるしかないです。

総評

自分の中ではstoryboard+xibを使って開発するのが今のところ一番良いのかな感じですね。
でも、やはりチーム開発をしているとコンフリクトはつきものだし、チームでコンポーネントの粒度は統一する必要があり、また適切な粒度でコンポーネントが切れていないとxibを使うメリットや余分にファイルを作ってしまう可能性もあります。
また、宣言的にUIが書けないことやAutoLayoutの設定もUIKitでの開発の辛いところなのかなって感じですね。

参考にしました🙏

参考URL1
https://qiita.com/shtnkgm/items/cad6f52c489612628fd4
参考URL2
https://qiita.com/takasek/items/3bc284149dcd8aecbf7c#ロードするとき-bundle-と-uinib-のどっち使えばいいの
参考URL3
https://engineering.mercari.com/blog/entry/2019-12-13-155700/
Codeを用いて作成のところのプロジェクト
https://github.com/tiking76/chatapp

Discussion