はじめに

まえがき

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

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

2018年10月8日に開催された技術書典5にて頒布致しました「iOSアプリ開発 UI実装であると嬉しいレシピブック」では、UI実装においてView構造やアニメーション実装等を上手に活用して少しの工夫を施すことで実現可能なアイデアや実装例についてまとめています。また2019年7月27日に開催された技術書同人誌博覧会にて頒布致しました「iOSアプリ開発 UI実装であると嬉しいレシピブック Vol.2」では、前回の続編として更にアプリにおけるUI表現に彩りを添えるためのテクニックとしてGithubで公開されているOSSのUIライブラリを活用するアイデアや実装例についてまとめています。さらに加えて2020年3月7日〜4月5日の期間で開催された技術書典応援祭にて頒布しました「iOSアプリ開発 UI実装であると嬉しいレシピブック まかない編」では、Vol.1及びVol.2では惜しくも紹介ができなかったUI実装やiOS13以降で新しく登場したUICollectionViewのレイアウトに関する新機能を利用したアイデアや実装例についてまとめています。

このように、これまではUI実装のアイデアや具体的な手法についてフォーカスを当てた書籍を3冊執筆してきましたが、急遽Vol.3の前段として更に番外編として表現や動きが特徴的でかつ、ユーザーにもほんの少しだけ遊び心を与えるような楽しい感覚を抱かせてくれるようなUI実装に関する解説を「おもしろ編(番外編Vol.2)」として簡単でありますがまとめたものになります。Chapter1及びChapter2で紹介しているサンプル実装についてはUIKitをベースに構築したサンプルとなっていますが、Chapter3ではiOS13から登場したSwiftUIを利用して構築したサンプルとなっております。

UIKitを利用して実装したサンプルにつきましては、指の動きに合わせた動きやインタラクションが楽しめる、少しトリッキーな実装を形になってしまうけれども面白いサンプルをご用意しています。またSwiftUIを利用して実装したサンプルにつきましては、筆者がまだそれほど慣れていないこともあったので少し規模は小さめではあるものの、iOSのアプリUIでよくお目ににかかる感じのUI実装を試しています。

本書では、これまでの実務の中で培ってきた知識や知見に加えて、一般的なiOSアプリに対しては利用可能なケースは限られてしまうかもしれませんが、アニメーションやインタラクションにひと工夫を加えることによって、見た目にも美しく触っていて思わず楽しくなりそうな感じのUI実装に関するサンプルを3点収録しております。

指の動きとの親和性を考慮した触り心地や操作感の良さを感じさせるような形の表現を実現するためのUI実装を考えていく上でヒントとなるUI実装の方法を考えていく際に、本書が少しでもお役に立つことができれば幸いです。そして、筆者自身もモバイルアプリのUI/UX関連の最新技術やトレンド等へのキャッチアップを怠ることなく、目に見えない細かな気配りや配慮の部分にも気を配らせながら、更に開発技術や表現の幅を広げていくと共に新たな技術や知識、そして知見を吸収していくと共により皆様が楽しむことができる様な形で展開していける様に精進していく所存でおります。

動作環境及びバージョン

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

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

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

【必要な前提知識】

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

サンプルに関して

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

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

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

  • Mail: just1factory@gmail.com

第1章

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


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

図1: 第1章のサンプル

第2章

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


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

図2: 第2章のサンプル

第3章

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


  • サンプルプロジェクト名: SmallSwiftUILayout
第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にしています。)

目次

はじめに

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

第1章 Photo Gallery & Transition

1.1 事前準備に関して
1.2 本章でのサンプル実装における概要
1.3 サンプル実装画面に関する説明
1.4 上下及び左右方向の同時スクロールを実現するレイアウトの実装解説
  • UICollectionViewFlowLayoutクラスを継承したクラスの作成
  • 上下及び左右方向のスクロールをするUICollectionViewの表示に関して
1.5 サムネイル一覧画面から拡大表示する形の画面遷移処理の実装解説
  • 画面遷移時のカスタムトランジションを実現するために必要なクラスの関連性
  • 画面遷移元の画面構造とカスタムトランジションを考える
  • 画面遷移先の画面構造とカスタムトランジションを考える
  • 指の動きと連動するインタラクティブな画面遷移処理を考える
  • UINavigationControllerを拡張してアニメーション等の処理と結びつける
1.6 Safariアプリのタブ表示に類似したレイアウトの実装解説
  • UICollectionViewLayoutクラスを継承したクラスの作成
  • Safariアプリのタブ表示の様な振る舞いをするUICollectionViewの表示に関して
1.7 UITabBarControllerの切り替えアニメーションの実装解説
1.8 UICollectionViewまたはUIScrollViewのどちらを利用するかの考察
1.9 コーヒーブレイク

第2章 Screen With Passcode Lock

2.1 事前準備に関して
2.2 本章でのサンプル実装における概要
2.3 サンプル実装画面に関する説明
2.4 利用したライブラリの紹介
  • PanModalの紹介
  • SwipeCellKitの紹介
2.5 本章のサンプルで利用しているアーキテクチャに関して
2.6 コンテンツ一覧からセミモーダルビューで表示する画面を実装する
  • 画面上部にくっつくスクロールをするUICollectionViewの動き
  • ライブラリ「PanModal」を利用したセミモーダルビュー表示
  • ライブラリ「SwipeCellKit」を利用したスワイプ処理でメニュー表示
2.7 パスコードロック機能にひと工夫を加えるためのポイント解説
  • 4桁のパスコードを入力するためのテンキー部分のView実装のポイント
  • ユーザーの入力状態を表す部分におけるView実装のポイント
  • TouchIDやFaceIDをパスコードロックを解除するために利用する際のポイント
2.8 パスコードロック画面を実装する
  • ユーザーが入力したパスコードを管理するModelとPresenterをつなげる
  • パスコード入力画面のViewControllerと用途に応じたPresenterをつなげる
  • SceneDelegate.swiftのライフサイクル処理と一番最初に表示する画面でのパスコードロックの実施する処理の解説
2.9 機能を更により良くするためのアイデアや導入時に注意すると良い点
2.10 コーヒーブレイク

第3章 Layout With SwiftUI

3.1 事前準備に関して
3.2 本章でのサンプル実装における概要
3.3 サンプル実装画面に関する説明
3.4 利用したライブラリの紹介
  • ASCollectionViewの紹介
  • WaterfallGridの紹介
3.5 本章における各画面を構成するView要素の分割に関して
3.6 ライブラリ「ASCollectionView」を利用した実装
  • Section毎の表示に必要なデータ要素を作成する
  • Section毎の表示に必要なView要素を作成する
  • Section毎のレイアウト定義を適用する
3.7 ライブラリ「WaterfallGrid」を利用した実装
  • 高さ可変のグリッド要素の表示に必要なデータ要素を作成する
  • 高さ可変のグリッド要素の表示に必要なView要素を作成する
  • WaterfallGridを利用したセルのグリッド表示を適用する
3.8 画面トップ位置に配置したサムネイル画像のパララックス表現部分の実装
3.9 本章のサンプルで利用しているその他ExtensionやUI調整に関する紹介
3.10 コーヒーブレイク

あとがき

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