- 投稿日:2020-05-29T22:38:59+09:00
【swift】セグメントでの分岐の仕方
セグメントの基本設定
UISegmentedControlの基本設定はstorybord上でできます。
セグメントの数や、それぞれに入れる文言はここで設定します。セグメントによって処理を分岐する
選ばれたセグメントの場所(番号)でスイッチするのが良いでしょう。
@IBOutlet weak var segmentedControl: UISegmentedControl! // セグメントコントロールが何番目に止まっているかでスイッチ switch segmentedControl.selectedSegmentIndex { case 0: break case 1: break case 2: break case 3: break default: break }
- 投稿日:2020-05-29T22:21:29+09:00
storybordでUIButtonを角丸にする方法
- 投稿日:2020-05-29T16:17:04+09:00
SF symbolsの使い方
iOSでよく使われる画像を使いたい
上のような画像が使いたい時、あると思います。
これらの画像はそれぞれ
Image(systemName: "paperclip")
Image(systemName: "folder.fill")
Image(systemName: "square.and.arrow.up")
で表示することができます。(SwiftUIを想定しています)App公式サイトにある download the SF Symbols app をクリックしダウンロードをし表示される手続きに従うと、Launchpadにアプリが追加されます。
このアプリでは上で表示したpaperclipなどの名前とその画像が表示されます。
あとは使いたい画像を選択し、Image(systemName: "")のようにすれば、画像を表示することができます。
- 投稿日:2020-05-29T14:14:13+09:00
Swiftでのビットによるカテゴリ分類の表現方法
ビットマスク
SpriteKitなどの物理エンジンではノード(オブジェクト)の衝突判定などにビットマスクを用いる。
ビットマスクをするために、ノードにはカテゴリとなるbitを割り当てる必要がある。
ビットマスクによる衝突判定処理は、簡単に言えばカテゴリ同士でAND演算を行い、結果が0以外なら有効(衝突)、0なら無効というふうに行う。
例えばノードA(カテゴリ: 0001)とノードB(衝突カテゴリ: 0001)は衝突するが、ノードC(衝突カテゴリ: 0010)とAは衝突しない。
カテゴリビットの定義
基本的にはenumに定義する。そのほうが保守性が高くなる。
最初はbit演算を使えばいけると思った。
mask.swiftenum Category: Int { case a = 1 << 0 case b = 1 << 1 case c = 1 << 2 case d = 1 << 3 case f = 1 << 4 case g = 1 << 5 case h = 1 << 6 case g = 1 << 7 ... }しかし、eunmは要素の初期化時に処理を行うことはできない。enumの値はリテラルである必要がある。
mask.swift:2:14: error: raw value for enum case must be a literal case a = 1 << 0 ^ mask.swift:3:14: error: raw value for enum case must be a literal case b = 1 << 1 ^ mask.swift:4:14: error: raw value for enum case must be a literal case c = 1 << 2 ...二進数(
0b
リテラル)を使う方法と十六進数(0x
リテラル)を使う方法が見やすくて良さそう。二進数
enum CategoryB: Int { case a = 0b0000000000001 case b = 0b0000000000010 case c = 0b0000000000100 case d = 0b0000000001000 case f = 0b0000000010000 case g = 0b0000000100000 case h = 0b0000001000000 case g = 0b0000010000000 ... }十六進数
enum CategoryX: Int { case a = 0x0001 case b = 0x0002 case c = 0x0004 case d = 0x0008 case f = 0x0010 case g = 0x0020 case h = 0x0040 case g = 0x0080 ... }それぞれの生の値は等しい。
assert(CategoryB.h.rawValue == CategoryX.h.rawValue)個人的には十六進数の方が文字が少なくて良い。
- 投稿日:2020-05-29T11:03:10+09:00
Xcode11でscrollViewを使う
ScrollViewをXcode11で使いたい!
Xcode11からscrollViewの設定のなんやかんやが結構変わったの!で!scrollViewの設定方法が変わりました!よ!
ググっても全然出てこなかったから備忘録として書く!早速やっていこう
1. ViewControllerにScrollViewを置く
このscrollViewをViewの中に配置して、
こんな感じで画面いっぱいに広げよう!
そしたらこんな感じで制約を追加
この状態だとまだこんな感じにXcodeに怒られるけど後で追加で設定するから今は気にしないように!2. ScrollViewにStackViewを置く
3. ScrollViewとStackViewをいい感じにする
StackViewからContent Layout Guideにcontrolキーを押しながらドラッグすると
こんな感じのポップアップが出るから、
上の4つにチェック入れよう
で今度はStackViewからFrame Layout Guideにcontrolキーを押しながらドラッグして、
Equal Widthにチェック!
でここまでやったらConstraintsを見てみて、
こんな感じで + 414とか + 896とかになってるやつを0にしよう!
4. ScrollViewにViewを置く
ここまでできたらViewを置くだけ!
こいつをScrollViewに置いて
高さを指定してあげれば
こんな感じになる!!!!
もう1個下にViewを置きたいときは
こうやって上のViewの一番下に持ってって、StackViewの表示が出るところで離せばオッケ!
追加したViewにも高さを指定してあげることを忘れずに!5.Viewの上になんやかんや好きなものを置く
いろいろ置こう!!!!
ViewControllerのサイズを大きくしてあげると作業しやすいかも?
6.完成!
動いた動画↓
一応Githubあげといた↓
https://github.com/sugijotaro/scrollView
- 投稿日:2020-05-29T11:03:10+09:00
Xcode11でScrollViewを使う
ScrollViewをXcode11で使いたい!
Xcode11からscrollViewの設定のなんやかんやが結構変わったの!で!scrollViewの設定方法が変わりました!よ!
ググっても全然出てこなかったから備忘録として書く!早速やっていこう
1. ViewControllerにScrollViewを置く
このscrollViewをViewの中に配置して、
こんな感じで画面いっぱいに広げよう!
そしたらこんな感じで制約を追加
この状態だとまだこんな感じにXcodeに怒られるけど後で追加で設定するから今は気にしないように!2. ScrollViewにStackViewを置く
3. ScrollViewとStackViewをいい感じにする
StackViewからContent Layout Guideにcontrolキーを押しながらドラッグすると
こんな感じのポップアップが出るから、
上の4つにチェック入れよう
で今度はStackViewからFrame Layout Guideにcontrolキーを押しながらドラッグして、
Equal Widthにチェック!
でここまでやったらConstraintsを見てみて、
こんな感じで + 414とか + 896とかになってるやつを0にしよう!
4. ScrollViewにViewを置く
ここまでできたらViewを置くだけ!
こいつをScrollViewに置いて
高さを指定してあげれば
こんな感じになる!!!!
もう1個下にViewを置きたいときは
こうやって上のViewの一番下に持ってって、StackViewの表示が出るところで離せばオッケ!
追加したViewにも高さを指定してあげることを忘れずに!5.Viewの上になんやかんや好きなものを置く
いろいろ置こう!!!!
ViewControllerのサイズを大きくしてあげると作業しやすいかも?
6.完成!
動いた動画↓
一応Githubあげといた↓
https://github.com/sugijotaro/scrollView参考
https://useyourloaf.com/blog/scroll-view-layouts-with-interface-builder/
https://youtu.be/KmE50giVuLA
- 投稿日:2020-05-29T09:51:55+09:00
こんなソースコードはイヤだ-システムに依存する処理には意味ある名前を
- 投稿日:2020-05-29T07:41:04+09:00
UITableViewのドラッグ・アンド・ドロップ・サポートの追加 / テーブルビュー (UITableView) 間のドラッグ
今日は何を学びますか?
アプリケーションのたくさんのテーブルビューにドラッグ・アンド・ドロップ・サポートを追加します。
テーブルビュー間でアイテムをドラッグ・アンド・ドロップできるようになります。
ストーリー
私はかわいい猫を3匹飼っていて、猫用のおもちゃも3つ持っています(実際にはもっとたくさん持っていますが、この例では3つだけということにしておきましょう)。どの猫がどのおもちゃを持っているか追跡したいと思い、簡単なアプリを作りました。
スタータープロジェクト
このチュートリアルに従っていただくために、
UITableView
が2つ以上あるアプリを持っている必要があります。この例では、1つのCollectionView
の中に3つのテーブルビューがあります。スタータープロジェクトはこちらからダウンロードしてください: https://github.com/mszmagic/DragAndDropNekoApp/tree/StartTemplate
リンク先で最初のバージョンをダウンロードしてください。
完成したプロジェクト
プロジェクトを直接
git clone
したら完成したプログラムが手に入ります。https://github.com/mszmagic/DragAndDropNekoApp
ドラッグのサポート
ドラッグがサポートされると、システムユーザーが
UITableViewCell
を長押しし、それをドラッグして現在のテーブルの表示から外に出せるようになります。tableView.dragInteractionEnabled = true tableView.dragDelegate = selfデリゲート (Delegate) インプリメンテーションの追加
/* Drag delegate */ extension catCollectionViewCell: UITableViewDragDelegate { func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { } }ここでは
UIDragItem
を提供する必要があります。UIDragItem
にはUITableViewCell
間で移動するデータが必要です。この例では、移動したいデータはオモチャの名前になります。まずオモチャの名前を入手し:
let toyName = toys[indexPath.row]次にこれを
Data
オブジェクト内にエンコードguard let toyNameData = toyName.data(using: .utf8) else { return [] }アイテムプロバイダーを生成し、
toyNameData
をこのプロバイダーにセット。let provider = NSItemProvider() provider.registerDataRepresentation(forTypeIdentifier: kUTTypePlainText as String, visibility: .all) { completion in completion(toyNameData, nil) return nil }ここで、その結果を戻す
let item = UIDragItem(itemProvider: provider) return [item]ただし、最初のネコの名前が必要になるので、これを
session.localContext
に保存session.localContext = catNameこれで1つのテーブル表示のセルをドラッグしてテーブル表示から外に出せるようになったはずです。そして、そのテーブル表示のセルを別のテーブル表示にドロップできるはずです。
でも、ここまでは送り手側の作業を完了しただけです。まだ、これから受け手側のコーディング作業が少し残っています。
ドロップ (Drop) サポートを追加する
ドロップサポートを使うと、別のオブジェクトを現在のビューにドロップできます。ドロップサポートを追加するには、まずテーブルビューにデリゲートを割り当てます。
tableView.dropDelegate = self次に、
delegate
を実装します:extension catCollectionViewCell: UITableViewDropDelegate { func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) { } }
coordinator.session
から2つの関数が必要になります。 (https://developer.apple.com/documentation/uikit/uidropsession)hasItemsConforming(to:)
https://developer.apple.com/documentation/swiftui/dropinfo/3284316-hasitemsconforming
この関数を使うと、ビューにドロップしたデータのタイプを確認することができます。この記事の1つ前の節で次のコード行を使ったことを思い出してください:
provider.registerDataRepresentation(forTypeIdentifier: kUTTypePlainText as String, visibility: .all) { completion inデータのタイプは
kUTTypePlainText as String
です。次のコードを実行して確認できます:if coordinator.session.hasItemsConforming(toTypeIdentifiers: [kUTTypePlainText as String]) { }loadObjects(ofClass:completion:)
この関数を使うと、
coordinator
内にあるデータオブジェクトを抽出できます。coordinator.session.loadObjects(ofClass: NSString.self) { (fetchedItems) in //TODO }func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) { //データのタイプは `kUTTypePlainText as String` です。次のコードを実行して確認できます if coordinator.session.hasItemsConforming(toTypeIdentifiers: [kUTTypePlainText as String]) { //この関数を使うと、`coordinator` 内にあるデータオブジェクトを抽出できます。 coordinator.session.loadObjects(ofClass: NSString.self) { (fetchedItems) in guard let toyName = fetchedItems.first as? String else { return } //TODO } } }そして、おもちゃの名前が分かれば、そのおもちゃを1匹目の猫から削除して、2匹目の猫に追加できます。
ここでは、おもちゃの名前、1匹目の猫の名前、2匹目の猫の名前が必要です:
おもちゃの名前:
名前の情報は変数toyNameから取得できます。
1匹目の猫の名前
次のコード行を書いたことを思い出してください:
session.localContext = catName猫の名前は
session.localContext
に保存してあるので、このコードを使って取得できます:if let originalCatName = coordinator.session.localDragSession?.localContext as? String { //1匹目の猫の名前 }2匹目の猫の名前
self.catName
を呼び出すことで取得できます。ドラッグ機能の追加に関するコードはここで見ることができます:https://github.com/mszmagic/DragAndDropNekoApp/blob/master/NekoApp/Views/catCollectionViewCell.swift#L50...L72
ドロップ機能の追加に関するコードはここで見ることができます:https://github.com/mszmagic/DragAndDropNekoApp/blob/master/NekoApp/Views/catCollectionViewCell.swift#L74...L93
データを更新する
これで、次のプログラム値が得られました。
- おもちゃの名前
- 最初の猫の名前
- 2番目の猫の名前次のことが必要です。
- 最初の猫からおもちゃを外す
- 2番目の猫におもちゃを追加する
- テーブルビューをリロードするこれら3つのタスクは
ViewController
で完了するため、プログラム・デリゲート (Delegate) を使用してこの情報を伝達できます。protocol dragAndDropActionDelegate: AnyObject { func moveToy(toyName: String, fromCat: String, toCat: String) }そして、そこでアクションを実行できるよう、このデリゲート (delegate) を
ViewController
内にインプリメントします。extension ViewController: dragAndDropActionDelegate { func moveToy(toyName: String, fromCat: String, toCat: String) { //最初の猫からおもちゃを外す var fromCatToys = catToys[fromCat] ?? [] fromCatToys.removeAll { (toyNameInArray) -> Bool in return toyNameInArray == toyName } catToys[fromCat] = fromCatToys //2番目の猫におもちゃを追加する var toCatToys = catToys[toCat] ?? [] toCatToys.append(toyName) catToys[toCat] = toCatToys //テーブルビューをリロードする collectionView.reloadData() } }テーブル (catCollectionViewCell) 表示に変数を登録。
//catCollectionViewCell.swift weak var delegate: dragAndDropActionDelegate?delegate 変数をセット:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { ... cell.delegate = self ... }そして、ドロップのアクションが実行されたときにデリゲートファンクションをコール。
self.delegate?.moveToy(toyName: toyName, fromCat: originalCatName, toCat: self.catName)データ配列のアップデートに関連するコードは以下の通り https://github.com/mszmagic/DragAndDropNekoApp/commit/97fb908ce09b031b07c6bbc835fe43a59a9780c2
完成したプロジェクト: https://github.com/mszmagic/DragAndDropNekoApp
- 投稿日:2020-05-29T07:41:04+09:00
UITableView のドラッグ・アンド・ドロップ (Drag & Drop)・サポートの追加
今日は何を学びますか?
アプリケーションのたくさんのテーブルビューにドラッグ・アンド・ドロップ・サポートを追加します。
テーブルビュー間でアイテムをドラッグ・アンド・ドロップできるようになります。
ストーリー
私はかわいい猫を3匹飼っていて、猫用のおもちゃも3つ持っています(実際にはもっとたくさん持っていますが、この例では3つだけということにしておきましょう)。どの猫がどのおもちゃを持っているか追跡したいと思い、簡単なアプリを作りました。
スタータープロジェクト
このチュートリアルに従っていただくために、
UITableView
が2つ以上あるアプリを持っている必要があります。この例では、1つのCollectionView
の中に3つのテーブルビューがあります。スタータープロジェクトはこちらからダウンロードしてください: https://github.com/mszmagic/DragAndDropNekoApp/tree/StartTemplate
リンク先で最初のバージョンをダウンロードしてください。
完成したプロジェクト
プロジェクトを直接
git clone
したら完成したプログラムが手に入ります。https://github.com/mszmagic/DragAndDropNekoApp
ドラッグのサポート
ドラッグがサポートされると、システムユーザーが
UITableViewCell
を長押しし、それをドラッグして現在のテーブルの表示から外に出せるようになります。tableView.dragInteractionEnabled = true tableView.dragDelegate = selfデリゲート (Delegate) インプリメンテーションの追加
/* Drag delegate */ extension catCollectionViewCell: UITableViewDragDelegate { func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { } }ここでは
UIDragItem
を提供する必要があります。UIDragItem
にはUITableViewCell
間で移動するデータが必要です。この例では、移動したいデータはオモチャの名前になります。まずオモチャの名前を入手し:
let toyName = toys[indexPath.row]次にこれを
Data
オブジェクト内にエンコードguard let toyNameData = toyName.data(using: .utf8) else { return [] }アイテムプロバイダーを生成し、
toyNameData
をこのプロバイダーにセット。let provider = NSItemProvider() provider.registerDataRepresentation(forTypeIdentifier: kUTTypePlainText as String, visibility: .all) { completion in completion(toyNameData, nil) return nil }ここで、その結果を戻す
let item = UIDragItem(itemProvider: provider) return [item]ただし、最初のネコの名前が必要になるので、これを
session.localContext
に保存session.localContext = catNameこれで1つのテーブル表示のセルをドラッグしてテーブル表示から外に出せるようになったはずです。そして、そのテーブル表示のセルを別のテーブル表示にドロップできるはずです。
でも、ここまでは送り手側の作業を完了しただけです。まだ、これから受け手側のコーディング作業が少し残っています。
ドロップ (Drop) サポートを追加する
ドロップサポートを使うと、別のオブジェクトを現在のビューにドロップできます。ドロップサポートを追加するには、まずテーブルビューにデリゲートを割り当てます。
tableView.dropDelegate = self次に、
delegate
を実装します:extension catCollectionViewCell: UITableViewDropDelegate { func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) { } }
coordinator.session
から2つの関数が必要になります。 (https://developer.apple.com/documentation/uikit/uidropsession)hasItemsConforming(to:)
https://developer.apple.com/documentation/swiftui/dropinfo/3284316-hasitemsconforming
この関数を使うと、ビューにドロップしたデータのタイプを確認することができます。この記事の1つ前の節で次のコード行を使ったことを思い出してください:
provider.registerDataRepresentation(forTypeIdentifier: kUTTypePlainText as String, visibility: .all) { completion inデータのタイプは
kUTTypePlainText as String
です。次のコードを実行して確認できます:if coordinator.session.hasItemsConforming(toTypeIdentifiers: [kUTTypePlainText as String]) { }loadObjects(ofClass:completion:)
この関数を使うと、
coordinator
内にあるデータオブジェクトを抽出できます。coordinator.session.loadObjects(ofClass: NSString.self) { (fetchedItems) in //TODO }func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) { //データのタイプは `kUTTypePlainText as String` です。次のコードを実行して確認できます if coordinator.session.hasItemsConforming(toTypeIdentifiers: [kUTTypePlainText as String]) { //この関数を使うと、`coordinator` 内にあるデータオブジェクトを抽出できます。 coordinator.session.loadObjects(ofClass: NSString.self) { (fetchedItems) in guard let toyName = fetchedItems.first as? String else { return } //TODO } } }そして、おもちゃの名前が分かれば、そのおもちゃを1匹目の猫から削除して、2匹目の猫に追加できます。
ここでは、おもちゃの名前、1匹目の猫の名前、2匹目の猫の名前が必要です:
おもちゃの名前:
名前の情報は変数toyNameから取得できます。
1匹目の猫の名前
次のコード行を書いたことを思い出してください:
session.localContext = catName猫の名前は
session.localContext
に保存してあるので、このコードを使って取得できます:if let originalCatName = coordinator.session.localDragSession?.localContext as? String { //1匹目の猫の名前 }2匹目の猫の名前
self.catName
を呼び出すことで取得できます。ドラッグ機能の追加に関するコードはここで見ることができます:https://github.com/mszmagic/DragAndDropNekoApp/blob/master/NekoApp/Views/catCollectionViewCell.swift#L50...L72
ドロップ機能の追加に関するコードはここで見ることができます:https://github.com/mszmagic/DragAndDropNekoApp/blob/master/NekoApp/Views/catCollectionViewCell.swift#L74...L93
データを更新する
これで、次のプログラム値が得られました。
- おもちゃの名前
- 最初の猫の名前
- 2番目の猫の名前次のことが必要です。
- 最初の猫からおもちゃを外す
- 2番目の猫におもちゃを追加する
- テーブルビューをリロードするこれら3つのタスクは
ViewController
で完了するため、プログラム・デリゲート (Delegate) を使用してこの情報を伝達できます。protocol dragAndDropActionDelegate: AnyObject { func moveToy(toyName: String, fromCat: String, toCat: String) }そして、そこでアクションを実行できるよう、このデリゲート (delegate) を
ViewController
内にインプリメントします。extension ViewController: dragAndDropActionDelegate { func moveToy(toyName: String, fromCat: String, toCat: String) { //最初の猫からおもちゃを外す var fromCatToys = catToys[fromCat] ?? [] fromCatToys.removeAll { (toyNameInArray) -> Bool in return toyNameInArray == toyName } catToys[fromCat] = fromCatToys //2番目の猫におもちゃを追加する var toCatToys = catToys[toCat] ?? [] toCatToys.append(toyName) catToys[toCat] = toCatToys //テーブルビューをリロードする collectionView.reloadData() } }テーブル (catCollectionViewCell) 表示に変数を登録。
//catCollectionViewCell.swift weak var delegate: dragAndDropActionDelegate?delegate 変数をセット:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { ... cell.delegate = self ... }そして、ドロップのアクションが実行されたときにデリゲートファンクションをコール。
self.delegate?.moveToy(toyName: toyName, fromCat: originalCatName, toCat: self.catName)データ配列のアップデートに関連するコードは以下の通り https://github.com/mszmagic/DragAndDropNekoApp/commit/97fb908ce09b031b07c6bbc835fe43a59a9780c2
完成したプロジェクト: https://github.com/mszmagic/DragAndDropNekoApp
- 投稿日:2020-05-29T01:13:59+09:00
【iOS】iOSアプリ開発入門~ 画面遷移編2~
はじめに
前回はsegueを使った画面遷移の方法とパラメータの受け渡しについて投稿しました。
画面遷移編2:https://qiita.com/euJcIKfcqwnzDui/items/679b1cd30694519f4916#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB前回の説明で「画面遷移の方式はいくつかある」というように説明しました。
今回はそのそれぞれの方式について説明します。前提
その前にアプリのUI、画面設計において覚えておいてほしいことがあります。
UI、または画面の目的は原則として1つにするということです。世の中に出回っているアプリを思い出してみるとわかるかもしれませんが、例えばボタンの場合、保存、削除、検索など1つのボタンが担う役割は基本的に1つです。
「このボタンは保存も削除も検索もできるボタン」ということにはなり得ません。画面についても同じことが言えます。
画面の場合はもう少し大きな機能ベースになります。
例えばログイン機能、カメラ撮影機能、動画の再生機能など。
この大きな機能については、どこまでを1機能として捉えるか人によって若干変わるかもしれませんし例外もあります。
ですが1画面に対して1機能が基本だということは覚えておきましょう。さらにいうとアプリが提供する機能も1つに限定すべきというのが本来の思想でもあります。
例えばiOSの標準アプリの場合、カメラと写真アプリはそれぞれ別アプリとして提供されています。
これはカメラで撮影する機能と写真を管理する機能は別機能として考えられているためです。
Googleアプリについても「Googleサービス」というまとまったアプリではなく、メール、ドライブ、カレンダーなどそれぞれの機能別でリリースされています。実際のところ複数の機能を提供してしまっているアプリは多く存在しますが原則として1アプリ1機能と認識しておいてください。
画面遷移の種類
少し話が逸れましたがアプリ内において各画面は提供する機能は異なります。
同じ「機能」というものではありますが、それぞれアプリ内での立ち位置が異なりその目的に合わせた画面遷移をさせるのが望ましいとされています。どういうときにどのような遷移を使った方がいいのかはAppleがHuman Interface Guidelinesで説明しています。
こちらにも一度目を通すことをおすすめします。
Apple Human Interface Guidelines - Modality -
Apple Human Interface Guidelines - Navigation -この画面遷移の方式は大きく3種類あります。
アニメーションの仕方もそれぞれ異なります。モーダル
これは前回説明した方式です。
このような下からにゅっと出てくるアニメーションで表現されます。
モーダルで開かれた画面はモーダル画面やモーダルウィンドウと言います。
modalは「モードを持つ」という意味で、アプリ機能の主軸とは違う一時的な処理をさせたい時などに使います。
モードが切り替わるというようなイメージでしょうか。
Apple Human Interface Guidelinesでは** Modality**と紹介されています。iPhoneのAppStoreではアカウント表示に使われています。
AppStoreはアプリの入手するためのアプリです。
アカウント情報やログインはアプリに必要な機能ではありますが、「アプリを入手する」というメイン機能とは違います。このようにアプリのメインタスクではなくサブタスクを行う場合はモーダルで画面を表示します。
プッシュ
最もよく見る遷移方式です。
右から画面がスライドしてくるアニメーションで表現されます。
プッシュは詳細が画面を表示する際に使用します。
AppStoreの場合はじめ多くアプリが表示されていますが、その1つをタップすると対象のアプリの詳細な画面が表示されています。
さらにその中からバージョン情報などをタップするとバージョン履歴が表示されるという構成になります。最もイメージしやすいのはiOS標準の設定アプリです。
複数の項目があり→詳細→詳細と遷移していきます。Apple Human Interface GuidelinesではHierarchical Navigationと紹介されています。
Hierarchicalとあるように根本となるルート画面があり、そこから階層構造になっています。タブ
最後はタブによる画面遷移です。
「タブ」とあるように画面最下部に表示されているタブをタップすると画面が切り替わるあれです。
基本的にアニメーションはなく即切り替わります。
タブは異なるカテゴリ間の遷移です。目的の画面の検索方法とでもいいましょうか?
とはいえ入りとなるカテゴリは別ですが、全て同じ目的に行き着きます。AppStoreでは[Today]、[ゲーム]、[App]、[Arcade]、[検索]というタブがあります。
ですが結局のところ目当てのアプリを見つけやすくしているだけで、どのタブからもアプリの画面にたどり着きます。Apple Human Interface GuidelinesではFlat Navigationと紹介されています。
Flat、つまりは並列です。
基本的に互いに影響は与え合わずそれぞれのタブがそれぞれルートとなる画面を持ちます。
AppStoreを見ればわかりますがそれぞれのルート画面からプッシュで遷移していくことも可能です。最後に
今回はiOSアプリの画面遷移の方式について紹介しました。
いつどの画面遷移を採用するのか、今はその概要さえ押さえられていれば大丈夫です。実際のところHuman Interface Guidelinesに書かれてはいるのですが、そこまで詳細ではないのでアプリによって多少違いがあります。
よくタブの1つにマイページタブを置くアプリを見ますが、本来はモーダルの役割ではないかなとも思ったりもします。
(あくまで私見ですのであしからず。。。)現場ではAndroidアプリも一緒に開発することが多いのですがAndroidにはAndroidの思想があり、どちらを採用するのかを話し合って決めます。
なので結局開発チームに依るところも多いので基本はこんな感じという認識でいてください。次回はプッシュ、タブ遷移の実装方法について説明します。
画面遷移編3:https://qiita.com/euJcIKfcqwnzDui/items/c0c0ccbd8d301b96d8b7本連載ではプログラミング未経験からiOSアプリ開発が行えるようになることを目的としています。
今までの投稿をまとめていますのでこちらもご覧ください。
アジェンダ:https://qiita.com/euJcIKfcqwnzDui/items/0b480e96166e88945684参考文献
- Human Interface Guidelines
iOSにおける3つの画面遷移を知る
【iOS】画面遷移方法まとめ