【Swift】少しの手間で出来る!iOS アプリの UX改善 Tips 教えます
ya_s_u
この記事は RECRUIT MARKETING PARTNERS Advent Calendar 2017 の投稿記事です。
はじめまして、『妊婦さんのためのアプリ 妊娠・出産なら Baby+』1)今年の9/7にリリースしました🎉のiOS開発を担当している2017新卒2)2015春インターンから気づいたら入社していましたエンジニアの後藤(@ya-s-u)です。
モバイルアプリの成功要因は様々な要素に依存していますが、使いやすくて愛されるアプリを作るには細かいユーザー体験にまで気を配る必要があります。今回は有名アプリなどでよく見る、工数はそこまでかからないけどアプリが少しだけ使いやすくなるUX改善Tipsを4つご紹介3)タップ領域を可視化するためconopsys/COSTouchVisualizerを使いましたします!
使いやすいアプリとは
使いやすいアプリには優れたサービス全体の設計が必要なのは大前提ですが、今回は以下の3点に注目します。
- 直感的に操作できる
- 次のアクションを迷わない
- アクションに対するフィードバックがある
iOSアプリのUI/UXに関しては、Appleの公式リソースを一度読んでみることをお勧めします。
UITableViewで遷移先から戻ってきたときにどれを見ていたのか教えてあげる
UITableViewの通常の実装では、遷移先から戻った場合に今までどのセルを選択していたのが分からず、ユーザーが迷ってしまうことがあります。遷移先から戻ってきたタイミングでハイライトを解除すると、どのセルを選択していたのかを明示してあげることができ、次のアクションを促せます。
Before | After |
---|---|
上記スクリーンショットのAfterを見ると、一覧画面に戻るタイミングで選択していたセルのハイライトが解除されており、選択していたセルが分かるようになっています。この挙動は、標準の設定アプリやTwitterアプリで確認できます。
実装方法
UIViewControllerを使っている場合は、画面表示前のタイミング(viewWillAppear)でUITableViewに定義されているindexPathsForSelectedRows: [IndexPath]?
プロパティを使い、現在選択中のセル一覧を取得します。次にdeselectRow(at indexPath: IndexPath, animated: Bool)
メソッドを使い、それぞれのセルの選択を解除します。
- indexPathsForSelectedRows - UITableView | Apple Developer Documentation
- deselectRow(at:animated:) - UITableView | Apple Developer Documentation
以下にコードで示します。
import UIKit
final class HogeViewController: UIViewController {
@IBOutlet private weak var tableView: UITableView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.indexPathsForSelectedRows?.forEach {
tableView.deselectRow(at: $0, animated: true)
}
}
}
UITableViewControllerを使っている場合は、clearsSelectionOnViewWillAppear: Bool
というプロパティが定義されていますが、これはデフォルトでtrue
になっているので特に対応は必要ありません。
UIScrollViewを使うときはスクロール可能なことを教えてあげる
UITableViewやUICollectionViewを使っている時は、同じようなコンポーネントが連続しているのでスクロールできることが分かりやすいですが、UIScrollViewを使っている場合はスクロール可能か分かりづらい場合があります。そこで、スクロールバーを一瞬出してあげることでスクロールできることを明示することができます。
Before | After |
---|---|
上記スクリーンショットのAfterを見ると、スクロールビューに遷移したタイミングでスクロールバーが一瞬表示され、そのページがスクロール可能だと分かります。
実装方法
画面表示後のタイミング(viewDidAppear)で、UIScrollViewに定義されているflashScrollIndicators()
メソッドを使います。
以下にコードで示します。
import UIKit
final class HogeViewController: UIViewController {
@IBOutlet private weak var scrollView: UIScrollView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
scrollView.flashScrollIndicators()
}
}
UINavigationControllerで画面のどこをスワイプしても戻れるようにしてあげる
UINavigationControllerは戻るボタンをタップするのではなく、画面端をスワイプすることでも前の画面に戻ることができますが、画面サイズが大きいiPhoneでは片手で画面端を操作することが困難な場合4)スマホの持ち方とその操作可能領域に関する記事があります。そこで、画面全体のどこをスワイプしても前画面に戻れるようにしてあげると、片手でも操作しやすくなります。
Before | After |
---|---|
上記スクリーンショットのAfterを見ると、画面のどこをスワイプしても前画面に戻れることが分かります。この挙動は、FacebookアプリやTwitterアプリで確認できます。
実装方法
forkingdog/FDFullscreenPopGestureというOSSライブラリを用いることで、簡単に実装できます。
まず、CocoaPods経由でライブラリを導入するため、Podfileに以下の指定をし、$ pod install
を実行します。
次に、UINavigationControllerのfd_fullscreenPopGestureRecognizer.isEnabled
プロパティをtrue
にします。
UIViewControllerを使っている場合のコードを以下に示します。
import UIKit
import FDFullscreenPopGesture
final class HogeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.fd_fullscreenPopGestureRecognizer.isEnabled = true
}
}
画面ロード中はプレースホルダを表示してあげる
API通信や時間のかかる処理の実行中にUIActivityIndicatorなどを用いてインジケータを表示させることはよくあります5)画面操作をブロックしてしまうHUDはあまりお勧めしません。インジケータでも処理中であることはユーザーに伝えられますが、プレースホルダを使うと処理完了後の画面を予測することができ、次のアクションにスムーズに移行できます。
Before | After |
---|---|
上記スクリーンショットのAfterを見ると、コンテンツが表示されるまでは画像や文字部分に灰色のプレースホルダが表示されていることが分かります。この挙動は、FacebookアプリやSlackアプリで確認できます。
実装方法
Juanpe/SkeletonViewというOSSライブラリを用いることで、簡単に実装できます。
まず、CocoaPods経由でライブラリを導入するため、Podfileに以下の指定をし、$ pod install
を実行します。
プレースホルダを表示させたいビューのisSkeletonable: Bool
プロパティをtrue
にします。次に、API通信や重たい処理を開始する前にUIViewのshowSkeleton()
メソッドを呼びアニメーションを開始します。(複数のビューに表示させる場合は、一番親のビューのshowSkeleton()
メソッドを呼ぶことで、再帰的6)再帰的に探索するコードに子ビューにも適用されます) そして、処理が終了したタイミングでUIViewのhideSkeleton()
メソッドを呼ぶことで、非表示になります。
UIViewControllerを使っている場合のコードを以下に示します。
import UIKit
import SkeletonView
final class HogeViewController: UIViewController {
@IBOutlet private weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label.isSkeletonable = true
view.showSkeleton()
// 擬似的に3秒遅延させる
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(3)) {
self.view.hideSkeleton()
self.label.text = "Hoge"
}
}
}
まとめ
今回は、有名アプリなどで採用されているUX改善Tipsを4つ紹介しました。どれも見逃されがちな細かい改善ですが、より使いやすいアプリを作るには欠かせないと思います。
本記事が、みなさまの開発に少しでもお役に立てれば幸いです。