はじめに

まえがき

まずは本書を手に取って頂きまして、本当にありがとうございます。筆者は現在、主にiOSアプリ開発(使用言語はSwift/Objective-C)を行っており、特にその中でもアプリのUI実装に関する部分のことに携わる機会が多くありました。

また業務以外の場所でも、僭越ながら皆様の前で登壇する機会を頂きその中でUI実装に関することをお話したり、TIPSを投稿する等の活動をこれまでも行ってきたり、勉強会の中で同業のエンジニアの方々との交流の中で「Web制作ではUI実装に関する紹介書籍があるならば、もしかしたらiOSアプリ開発においてもUI実装に関する書籍の需要はあるのではないか?」と感じることもありました。さらには筆者のキャリアのはじめがデザイナーから始まり、そこからWebエンジニアを経てモバイルアプリエンジニアになった経緯もあったので、今でもUI実装に関する部分に一番関心が高い部分です。

2018年10月8日に開催された技術書典5にて頒布致しました、「iOSアプリ開発 UI実装であると嬉しいレシピブック」シリーズの続編にあたるものになります。お陰様で当日は数多くの来場者の方々に書籍を手に取って頂き本当に嬉しく思うと共に、改めて今後とも丁寧かつ有益な情報を提供できるようしていきたいと強く感じた次第でした。

前回の書籍は、基本的なUIKitの特性を利用した表現における工夫や、カスタマイズしにくい部分のポイントにUIライブラリを活用する方法についての解説を中心に行なってきました。シリーズ第2弾としては、さらにGithubで公開されているUI実装時に活用できそうなライブラリを上手に盛り込んだレイアウト実装のサンプルを紹介していきます。

実際にiOSアプリを開発する際には、githubや情報サイト等で紹介されているUIライブラリを導入したり、またはライブラリの内部実装を参考にして機能の一部分を切り出して自前で実装したりライブラリをForkして利用する場合もあるかと思います。しかしながらライブラリを知ることはできても、いざ実際に導入してみると、実際のアプリで想定していた実現したい表現との齟齬が生じてしまったり、ライブラリの上手な組み合わせ方を見出すまでに苦労をした経験をしたことがあるかと思います。

本書ではUIライブラリを導入したサンプル実装の解説を通じて、「このライブラリを活用することで享受できるメリットはどの部分か?」「類似UIを自前で実装する際に押さえておくべきポイントとなりうるのはどの部分か?」という点についてもご紹介できればと考えております。実際のアプリ開発におけるUI実装への布石なるような実践事例をこれまでに筆者が勉強会での発表してきた内容や開発サンプルを元に調整を加えたものを3点収録しています。

基本的な理解ができるようになって、これからiOSアプリを本格的に開発していこうと考えている方や、UI実装や表現に関する部分にさらなる磨きをかけていきたい方にとって本書が少しでもお役に立つことができれば幸いです。そして、筆者自身も現状に甘んじることなく自分の開発技術や表現の幅を広げる努力を惜しまずに歩み続けていこうと思う所存です。

動作環境及びバージョン

本書の内容及び紹介しているサンプルのコードに使用したバージョンにつきましては、下記の通りになります。またXcodeやSwiftのバージョンが上がった際にはGithubリポジトリ等、何かしらの形でお伝えしていく予定です。

掲載しているサンプルに関しては、2020.12.26(Ver1.2改訂時)のものになります。

  • macOS Big Sur 11.0.1
  • Xcode 12.3
  • Swift 5.3
  • CocoaPods 1.10.0

※ サンプルで利用しているライブラリの中にはSwift4.2のまま利用しているものがあります。


【必要な前提知識】

  • XcodeやSwiftに関する基本的な知識
  • AutoLayoutやStoryboard・Xibに関する基本的な知識
  • CocoaPodsの導入や活用に関する基本的な知識
  • iOSアプリ開発においてサードパーティー製ライブラリの導入や活用に関する基本的な知識

※ このサンプルの第2章ではnode.jsを利用した仮のAPIサーバーを準備していますが、あくまでツールとしての利用なので前述の前提知識としては特になくても大丈夫かと思います。(実際に手元でサンプルを実行する場合にはnode.jsのインストールが必要になるのでその点はご注意下さい)

サンプルに関して

書籍で紹介しているサンプルのリポジトリは下記になります。


誤表記などに関するお問い合わせに関して

本書で掲載している内容につきましては、誤りがないように細心の注意を払っておりますが、もし訂正等がございましたら下記にありますメールアドレスや、GithubのissueやTwitter等を通してでも構いませんので、ご一報頂けますと幸いです。

  • Mail: just1factory@gmail.com

第1章

サンプル実装の難易度: ★★★★★★★☆☆☆


  • サンプルプロジェクト名: TypicalAnimationContents
第1章のサンプル

図1: 第1章のサンプル

第2章

サンプル実装の難易度: ★★★★★★★★☆☆


  • サンプルプロジェクト名: MediaStyleAnimationContents
第2章のサンプル

図2: 第2章のサンプル

第3章

サンプル実装の難易度: ★★★★★★★★★☆


  • サンプルプロジェクト名: PurchasePresentContents
第3章のサンプル

図3: 第3章のサンプル

iOS14から利用可能な新機能や仕様変更に関する補足事項

本書ではiOS14から追加されたUI実装に関する新機能や仕様変更のうち、

  1. UINavigationController左上にある戻るボタンをロングタップした際に一気に最初の画面に戻る機能への対応
  2. URLを外部ブラウザで開く処理においてSafari以外をデフォルトブラウザに設定している場合にcanOpenURLがfalseとなる点への対応

の2点に関しては対応しております。

該当箇所に適用するコード例については、「リスト1」の様な形となります。

リスト1: iOS14からの新機能対応部分に関するコード解説

// UI実装であると嬉しいレシピブック掲載サンプル変更点(iOS14対応箇所)
// 1. UINavigationController左上にある戻るボタンをロングタップした際に一気に最初の画面に戻る機能への対応
// 本書の中では、UINavigationControllerExtension.swiftに該当箇所があります。
// 戻るボタンの「戻る」テキストを削除した状態にするメソッド
func removeBackButtonText() {
    self.navigationController!.navigationBar.tintColor = UIColor.white
    if #available(iOS 14.0, *) {
        self.navigationItem.backButtonDisplayMode = .minimal
        self.navigationItem.backButtonTitle = self.navigationItem.title
    } else {
        let backButtonItem = UIBarButtonItem(
            title: "", style: .plain, target: nil, action: nil
        )
        self.navigationItem.backBarButtonItem = backButtonItem
    }
}

// 2. URLを外部ブラウザで開く処理においてSafari以外をデフォルトブラウザに設定している場合にcanOpenURLがfalseとなる点への対応
// 本書の中では、当該処理に関する部分は下記の様な形で実装しています。
private func showWebPage() {
    if let url = URL(string: "http://www.example.com/") {
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:])
        } else {
            showAlertWith(completionHandler: nil)
        }
    }
}

// MEMO: iOS14からSafari以外のブラウザをデフォルトに変更することが可能です。
// その場合には「LSApplicationQueriesSchemes」の設定をしないとcanOpenURLでfalseになってしまいます。
// ※ 詳細はInfo.plistを参照
// 確認したSafari以外のブラウザは下記の通りになります。
// 検証ブラウザ: Google Chrome / Opera / Microsoft Edge / Firefox
private func showAlertWith(completionHandler: (() -> ())? = nil) {
    let alert = UIAlertController(
        title: "リンクを開くことができませんでした。",
        message: "アプリ内部の設定が誤っている可能性があります。",
        preferredStyle: .alert
    )
    let okAction = UIAlertAction(title: "OK", style: .default, handler: { _ in
        completionHandler?()
    })
    alert.addAction(okAction)
    self.present(alert, animated: true, completion: nil)
}

iOS14以降で利用可能なアップデートにつきましては、UICollectionViewに関するレイアウト表現及び実装に関するアップデートやUIImagePickerControllerにとって変わるPHPickerViewControllerといった新しいAPIの登場による大きなアップデートだけではなく、前述したコードの様に頻出な表現に関する細かな部分に関するアップデートもありました。掲載しているサンプルコード内での対応についてはUI実装や表現上最低限の対応としていますが、更に細かな*1こちらの資料や*2こちらの技術ブログ記事等に掲載している内容を参考にしながら変更点の概要と対処方法を知っておくとより理解が深まるように思います。

今回例示した資料や技術ブログの他にも、様々なiOS14から利用できる新機能やバージョンアップ時のノウハウをまとめてくださっているものもたくさんありますので、多くの情報に触れながら機能開発を進めていく様にすると良いではないかと感じております。

サンプルにおけるiOS13以降の機能や変更に未対応の部分

本サンプルでは下記の部分に関しては、今回は対応していませんのでご注意下さい。

  • DarkModeの無効化(現在は強制的にLightModeにしています。)
  • SceneDelegateの利用(現状は挙動に問題はありませんが非推奨です。)

目次

はじめに

まえがき
動作環境及びバージョン
サンプルに関して
誤表記などに関するお問い合わせに関して
  • 第1章
  • 第2章
  • 第3章
  • iOS14から利用可能な新機能や仕様変更に関する補足事項
  • サンプルにおけるiOS13以降の機能や変更に未対応の部分

第1章 TabBar Animation & Layout

1.1 事前準備に関して
1.2 本章で収録しているサンプル実装における概要
  • それぞれの画面における実装と役割について
1.3 利用したライブラリの紹介
  • Fontawesome.swiftの紹介
  • TransitionableTabの紹介
1.4 このサンプルで利用している便利なExtension集
  • 頻出部分の実装を扱いやすくするためのExtension
  • UITableView・UICollectionViewを扱いやすくするためのExtension
1.5 TabBarControllerの切り替え時にアニメーションを付与する
  • UITabBarControllerを継承したクラスを実装する
  • UITabBarItemと押下時にバウンドするアニメーションを実装する
  • TransitionableTabで定義されているアニメーションを実行するためのコードを実装する
1.6 部品となるViewを実装する
  • Xibを使用した部品単位でのView分割とベースとなるクラスを実装する
  • 角丸のカード状デザインのViewを実装する
1.7 このサンプルで利用しているアーキテクチャ
  • UICollectionViewでの一覧表示における実装例
1.8 UITableViewでのコンテンツ一覧表示に関する実装
  • AutoLayoutの制約値の更新を利用して配置した画像に視差効果を加える
  • スクロール時にセル要素がフェードインして出現するアニメーションを加える
1.9 UICollectionViewでの画像コンテンツ表示に関する実装
  • UICollectionViewLayoutAttributesをカスタマイズするための参考資料
  • UICollectionViewで「Masonry Layout」を実現するクラスを作成する
1.10 コーヒーブレイク

第2章 API Connection & Layout

2.1 事前準備に関して
  • node.js製のjson-serverに関する簡単な紹介
2.2 本章で収録しているサンプル実装における概要
  • それぞれの画面における関連性と役割について
2.3 利用したライブラリの紹介
  • BTNavigationDropdownMenuの紹介
  • Floatyの紹介
  • FSPagerViewの紹介
  • Toast-Swiftの紹介
  • ActiveLabel.swiftの紹介
  • AlamofireImageの紹介
  • SwiftyJSONの紹介
  • APIリクエスト結果をハンドリングする処理で利用したライブラリの紹介
  • その他利用しているライブラリについて
2.4 このサンプルで利用しているアーキテクチャや画面構成について
  • NotificationCenterを利用したデータバインディング
  • 記事一覧表示のAPIレスポンスをEntity構造に合致する形に変換する処理の概要
  • ページング処理を考慮したMVVMパターンでの記事一覧データのハンドリングから表示までの処理
  • UIScrollViewとUIStackViewを組み合わせた一覧表示画面において表示データや通信結果を考慮した表示について
2.5 各種画面表示をするViewControllerから見る実装ポイント
  • 記事詳細表示画面における実装ポイント
  • WKWebViewでQiita記事を表示する画面における実装ポイント
2.6 API通信処理に関連する部分テストコードについて
  • MockとStubを利用したAPI通信処理の代わりとなるものを準備する
  • 各種API通信処理を伴う画面で利用しているViewModelをテストする
2.7 コーヒーブレイク

第3章 Modify Transition & Layout

3.1 事前準備に関して
3.2 このサンプル実装における概要
  • それぞれの画面における関連性と役割について
  • UI表現でライブラリを利用している部分の概要
3.3 利用したライブラリの紹介
  • Cosmosの紹介
  • PINRemoteImageの紹介
  • SkeletonViewの紹介
  • PinterestSegmentの紹介
  • AnimatedCollectionViewLayoutの紹介
  • DeckTransitionの紹介
  • FloatingPanelの紹介
  • ARNTransitionAnimatorの紹介
  • その他利用しているライブラリについて
3.4 このサンプルで利用しているアーキテクチャや画面構成について
  • データ表示部分のアーキテクチャ
  • Storyboardの構成とUIPageViewControllerを組み合わせる
  • UIStackViewを利用したUI表現におけるTIPS紹介
3.5 各種画面表示をするViewControllerから見る実装ポイント
  • 商品一覧表示の画面における実装ポイント
  • 商品詳細表示の画面における実装ポイント
3.6 コーヒーブレイク

あとがき

今回の執筆に当たって
筆者プロフィール
試し読みはここまでです。
この続きは、製品版でお楽しみください。