20200914のiOSに関する記事は13件です。

配列について

1.はじめに


今まで範囲型やストライド型などを解説してきましたが、最も基本的ともいえるであろう配列について何も触れていなかったので、今回は解説していこうと思います。

2.配列とは


説明は不要だとは思いますが、念のために説明しておきます。
配列とはArray型のことを指していて、Array型とは1つの箱の中に、いくつかのデータが格納されているもののことを言います。このように複数個の要素を格納できるデータ構造のことを、コレクションといいます。

3.コレクションの内容の変更


コレクションの内容を変更するには、それが定数ではなく、変数に代入されている必要があります。
今説明しているArray型は構造体として定義されているデータ型で、配列のインスタンスを変数に代入したり、関数に対して引数として渡したりする際、必要に応じて新しいインスタンスが作成され、元の配列の内容に影響しないように動作します。
よってコレクションを変更したい場合、元の配列の値を保持するのか、または変更してもいいのかについて、検討する必要があります。
配列に対する操作には、配列の内容を変更するものと、新しい配列を値として返すものの2パターン用意されている場合があります。
例えば内容を昇順にソートするメソッドには、配列の内容を変更するsort()と、ソートされた配列を返すsorted()があります。

tmp1.sort()                //変数tmp1の内容が変更される
let tmp3 = tmp2.sorted()   //定数tmp2の内容は変更されず、結果はtmp3に入る

4.配列の部分的な置換


配列の添字として範囲を指定しておき、別の配列を代入すると、その部分を新しい内容に置き換えることができます。置き換える前と後の要素の個数は一致していなくても大丈夫です。以下の例を確認してください。

var s = ["春", "夏", "秋", "冬"]

s[0...0] = ["春休み", "お花見", "入学式"]  // s[0]はエラー
print(s)        // ["春休み", "お花見", "入学式", "夏", "秋", "冬"]を出力

s[1...3] = ["梅雨", "夏休み", "プール"]
print(s)        // ["春休み", "梅雨", "夏休み", "プール", "秋", "冬"]を出力

s[3...4] = []   // 削除にも使える
print(s)        // ["春休み", "梅雨", "夏休み", "冬"]を出力

5.部分配列の型


先ほど例を示したように、配列の添字に範囲を指定すると部分配列を得ることができます。
片側範囲を指定することもでき、先頭から途中まで、または途中から末尾までの部分配列になります。[...]ですべての要素を含む部分列も指定できます。以下を確認してください。

var days = ["日", "月", "火", "水", "木", "金", "土"]
print(days[2...4])  // ["火", "水", "木"]
print(days[...2])   // ["日", "月", "火"]
print(days[5...])   // ["金", "土"]
print(days[...])    // すべての要素を表示

ただし、得られた部分配列の型はArray型ではなく、ArraySlice型という型になります。
ArraySlice型も同様に利用できますが、添字を使って要素にアクセスする場合には、部分配列を指定したときの範囲で利用可能になるので、注意が必要です。
つまり必ずしも0から添字が使えるわけではなく、以下の例ならば3、4のみが利用できます。

let sub = days[3..<5]   // subはArrayIndex型。["水", "木"]
print(sub.count)        // 3を出力(要素が3つ)
print(sub.startIndex)   // 3を出力(最初の添え字は3)
print(sub[3])           // "水"を出力
print(sub[4])           // "木"を出力

ここでArray型が必要になったときに、ArraySlice型からArray型を得ることができます。

print(sub[3])                 // subはArraySlice型("水"を出力)
let subarray = [String](sub)  // Array<String>のイニシャライザ
print(subarray[0])            // 添字が0からになる("水"を出力)

6.配列同士の比較


配列同士を比較するために、「==」と「!=」を利用することができます。
「==」は、2つの配列の要素数が等しく、先頭から順番に対応する要素がそれぞれ等しいときにのみ真になります。以下の例を見てください。

let a = [1, 2]
let b = [2, 1]
a == b                 // false
a + [1] == [1] + b     // true([1, 2, 1]が構成されたため)

7.おわりに


応用的な部分にはあまり触れられていませんが、今回は様々な言語でとても中心的な要素となる、配列について解説しました。
利用する機会はすごく多いと思うので、基本的な活用方法などはきっちりと押さえておきましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UIView の updateConstraints() について知る

今回は View の制約を更新する際などに登場する updateConstraints() について簡単にまとめていきます?

なんのメソッド?

このメソッドはUIView のインスタンスメソッドで、View の制約を更新する際に呼び出します。基本的にはシステム側がレイアウトパフォーマンスを考慮したタイミングで呼び出すので、開発者が意図的に呼び出してはいけません。

いつ使うのか?

ある View に指定する制約が遅くパフォーマンスに影響を与える場合や冗長な変更を多数している場合にのみ、UIView のサブクラスでメソッドを Override して使用します。また、更新処理の最後でsuper.updateConstraints() を呼び出す必要があります。

    override func updateConstraints() {
        //
        // 制約の更新
        //
        super.updateConstraints()
    }

基本的には、あるアクションに伴う制約の更新などをする際は逐次そのスコープで制約を更新した方がシンプルですが、先述の通りパフォーマンスを大きく損なうような制約の更新などの場合は updateConstraint() 内で行なった方がいいよ〜とのことです?これは、updateConstraint() がレイアウトののバッチ処理を行いメインスレッドをブロックしないためです。

意図的に呼び出したい場合は?

setNeedsUpdateConstraints() という UIView のインスタンスメソッドを使用して、制約更新のフラグをつけることができます。これによって、指定された View とその Subviews がシステムのタイミングによって updateConstraint() を呼ぶようになります。また、更新を即座に行う必要がある場合には updateConstraintsIfNeeded() を使うことで即座に制約更新を行わせることができます。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

bluetooth マイク音声aacエンコードするとAudioFormatUnsupportedエラー

現象

Airpodsなどのbluetooth micがついてるデバイスで音声データ取得して、aac変換するエンコーダ設定、bitrate設定部分でAudioFormatUnsupportedエラーがでる。

理由

bluetooth micの企画samplerateは8khzか、16khzさかサポートしてなくて、エンコーダ設定部分で高いbitrate設定するとエラーがでる。今回は96kbps設定しようとしてました。

MacのAudio MIDI Setupで確認できる
image.png

解決方法

bitrate設定を小さくする.
16khz以下場合は32kbpsする. ステレオの場合は*1.5で大丈夫。

// audioのsamplebufferから取得
 AudioStreamBasicDescription *srcDesc= CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)CMSampleBufferGetFormatDescription(sb));

 int samplerate = srcDesc.mSampleRate;
 int bitrate = 96000;

 // 16khz以下の場合はbitrate小さくする
 if(samplerate <= 16000) {
   bitrate = 32000;
 }
 UInt32 sz = sizeof(bitrate);
 OSStatus r = AudioConverterSetProperty(mConverter, kAudioConverterEncodeBitRate, sz, &bitrate)

参考

image.png

bluetooth audio
https://www.silabs.com/documents/login/presentations/Developing-Bluetooth-Audio.pdf

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ディープラーニングで似顔絵生成。WarpGANをiOSで使う。

似顔絵を生成できるWarpGAN

スクリーンショット 2020-08-13 22.38.11.png

スクリーンショット 2020-09-14 20.54.14.png

Core MLに変換すれば、Image Picker Controllerなどから画像を入力するだけで似顔絵が生成できます。
CoreMLTools4.0になって変換できるようになりました(tfcoremlでは変換できなかった)。
変換済みCore ML モデル

1、グラフをpbtxt形式にする。

warpgan.py
tf.io.write_graph(self.sess.graph_def, '', 'warpgan.pbtxt')

*allow_pickleを設定する必要がありました

detect_face.py
data_dict = np.load(data_path, encoding='latin1',allow_pickle=True).item()

2、チェックポイントから凍結グラフを作る。

from tensorflow.python.tools.freeze_graph import freeze_graph

graph_def_file = 'warpgan.pbtxt'
checkpoint_file = 'warpgan_pretrained/ckpt-100000'
frozen_model_file = './frozen_model.pb'
output_node_names = 'Decoder/Decoder/images_rendered'

freeze_graph(input_graph=graph_def_file,
             input_saver="",
             input_binary=False,
             input_checkpoint=checkpoint_file,
             output_node_names=output_node_names,
             restore_op_name="save/restore_all",
             filename_tensor_name="save/Const:0",
             output_graph=frozen_model_file,
             clear_devices=True,
             initializer_nodes="")

3、coremltoolsで変換する。

import coremltools as ct
image_input = ct.ImageType(shape=(1, 256, 256, 3,),
                             scale=2/255,bias=[-1,-1,-1])

coreml_model = ct.convert(
        "frozen_model.pb",
        inputs=[image_input],
        )
coreml_model.save("warpgan.mlmodel")

Visionで顔まわりでクロップしてからモデルにかけると綺麗に変換できます。

result_4.jpg

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

Twitter
MLBoysチャンネル
Medium

相棒
note

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【2020年版】3ステップでFlutterのHelloWorldをやってみる

細か事は抜きにして3ステップ使って、iOSシミュレータでFlutterのHelloWorldをやってみます。

ステップ1.Flutterのインストール

公式サイトに沿って進めていきます。

いくつか方法が提供されていますが、gitでFlutterSDKをダウンロードします。

$ git clone https://github.com/flutter/flutter.git -b stable --depth 1

ステップ2.Flutterの開発環境を整える

FlutterSDKへのパスを通します。

export PATH="$PATH:【絶対パス】/flutter/bin"

僕はzshを使用しているので、~/.zshrcに以下のパスを追加してFlutterSDKへのパスを通します。
※パスが通っているかはwhich flutterで確認してください。何も出力されなければパスは通っていません

$ flutter precache

ちょっと時間がかかりますが、開発バイナリの事前キャッシュをします。
(公式に記載があるので実行しています)

ステップ3.アプリ作成から実行

以下のコマンドでHelloworldという名のFlutterプロジェクトを作成し、カレントディレクトリをプロジェクトフォルダに移動させておきます。

$ flutter create Helloworld
$ cd Helloworld

iOSシミュレータで実行

$ open -a Simulator

iOSシミュレータで実行するために以下のコマンドで事前にシミュレータを起動させておきます。

$ flutter run

runコマンドを実行し、シミュレータでFlutterアプリが起動します。

特にトラブルなくアプリ実行できました。

まとめ

今回は細かいことは抜きにして動くことを最優先でFlutterのHelloworldをやってみました。
僕は慣れているからという理由で今までゲームじゃないものもUnityで作ってたのですが、 ゲームではないアプリケーションの開発手段の幅をFlutterで広げてみようと思います。

最初気づかなかったのですが、ホットリロードが出来ることを知ってイテレーションを早く回せて開発しやすそう!って思いました(始めたばかりだけど)。

環境

- macOS Catalina 10.15.5
- Flutter 1.20.3 • channel stable • https://github.com/flutter/flutter.git
- Framework • revision 216dee60c0 (11 days ago) • 2020-09-01 12:24:47 -0700
- Engine • revision d1bc06f032
- Tools • Dart 2.9.2
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS14 IDFA取得時の挙動を実機で検証してみる

2020/09/16:追記

iOS14 GMでも、同じ挙動となる事を確認しました。
日本時間 9月17日にリリースされる正式版でも恐らく同じ動きになる可能性が高いと思われます。

概要

iOS14(ベータ版)では、常にisAdvertisingTrackingEnabledがfalseを返してくる様です。

AdSupport FrameworkのisAdvertisingTrackingEnabled

iOS13までの「追跡型広告を制限」をチェックする為のフラグでしたが

iOS14でDeprecatedとなりました。

先日リリースされたiOS14 beta8で、実際の挙動について検証してみました。

環境

  • xcode12.0 beta 6
  • iOS14 beta8
  • iPhoneX(トラッキング制限設定無し)

結果

結果は以下の通り

ビルド isAdvertisingTrackingEnabled IDFA
iOS13向け false 取得OK
iOS14向け(IDFA許諾は未決定。ダイアログ出していない) false 取得OK

やはり、ユーザのIDFA許諾状況に依らず、isAdvertisingTrackingEnabledは常にfalseが返ってくる結果でした。

つまり、現在リリースしているアプリをiOS14で実行した場合。

iOS13で追跡型広告を制限(LAT)していなかったユーザであっても、iOS14では「制限あり」と判断してしまいます。
(従来コードのままだと、IDFAを取得しないフローに流れてしまう)

懸念

多くのアプリが、isAdvertisingTrackingEnabledをチェックせずにIDFAを取得するフローは、審査上取っていないと思います。

このままの仕様でリリースされた場合、

せっかくIDFA許諾必須化が来年初旬まで延期されたにも関わらず

この挙動に対応していないアプリからは「IDFAが取得出来ない」状況になる可能性が高いです。

対策

この仕様への対策として

AppTrackingTransparencyの許諾ステータスをチェック

許諾済み以外の場合、まずIDFAを取りにいき

返値がゼロ以外であれば、そのままIDFA使用

と言ったパターンなどが考えられます。

例えば

func isAvailableIDFA() -> Bool {
        if #available(iOS 14.0, *) {
            if ATTrackingManager.trackingAuthorizationStatus == .authorized {
                return true
            }else{
                // .authorized以外
                // 有効なIDFAか?
                return !isZeroIDFA()
            }
        }else{
            // iOS13以下
            return ASIdentifierManager.shared().isAdvertisingTrackingEnabled
        }
}

func isZeroIDFA() -> Bool {
        return (ASIdentifierManager.shared().advertisingIdentifier.uuidString == UUID(uuid: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)).uuidString)
}

ただ、この辺りの最終的な挙動はもうすぐ出るであろうGM版で、どうなるかまだわかりません。

引き続き、チェックしていきたいと思います。


参考
https://developer.apple.com/documentation/adsupport/asidentifiermanager/1614148-isadvertisingtrackingenabled
https://developer.apple.com/documentation/apptrackingtransparency

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Human Interface Guidelines part2

ユーザーインタラクション

3D Touch

サポートされているデバイスでは、タッチスクリーンにさまざまなレベルの圧力を加えることで、追加の機能にアクセスできます。
ビッてメニューが出ます。
iOS 13以降を実行しているデバイスでは、デバイスが3Dタッチをサポートしているかどうかに関係なく、長押しでメニューが出ます。

アップルペンシル

Apple Pencilは、iPadアプリでメモをメモしたり、スケッチしたり、ペイントしたり、ドキュメントをマークアップしたりするときに、ピクセルレベルの精度を提供する多用途で直感的なツールです。
利き腕の設定もできます。

オーディオ

※開発者向けの部分のみ

ボリュームビューはカスタマイズ可能で、音量レベルのスライダーが含まれ、MPVolumeViewフレームワークで利用可能です。
短い音やバイブレーションには、システムのサウンドサービスを使用してください。
必要がない場合は、他のアプリからの音楽の再生を停止させないでください

認証

追加機能へのアクセス、コンテンツの購入、データの同期など、ユーザにとって価値がある場合にのみ認証を要求します。
アプリで認証が必要な場合は、Appleでのサインインを使用して、簡単で安全なサインイン方法を提供します。
Appleでのサインインをサポートすると、信頼できる一貫したサインインエクスペリエンスと、複数のパスワードを覚えておく必要がないという便利さを実現できます。

Appleでのサインインを使用しない場合は、パスワードオートフィルを使用

パスワードオートフィルを使用することで、
パスワードとセキュリティコードを自動的に生成して入力するため、認証画面に費やす時間を短縮できます。
すべてのアプリがこの機能をサポートする必要があります。
https://developer.apple.com/documentation/security/password_autofill/

サインインを可能な限り直前に行う

ユーザーは、機能を利用する前にサインインを余儀なくされたとき、アプリを放棄することがよくあります。

アプリを使用する前に、アプリに恋する機会を与えましょう。(アプリに恋する機会っておしゃれですな)

認証の利点と、サービスにサインアップする方法を説明する

アプリで認証が必要な場合は、要件の理由とその利点を説明する簡潔でわかりやすい説明をログイン画面に表示します。

適切なキーボードを表示して、データ入力を最小限に抑えます。

たとえば、電子メールアドレスを要求する場合は、電子メールのキーボード画面を表示します。
この画面には、便利なデータ入力ショートカットが含まれています。
UIKeyboardType

パスコードという用語は決して使用しないこと

パスコードは、生体認証が無効になっているときに、ユーザーのiOSデバイスのロックを解除し、Apple Payで認証するために使用されます。

常に認証方法を識別する

たとえば、Face IDを使用してアプリにサインインするためのボタンのタイトルは、「Sign In」ではなく「Sign In with Face ID」にする必要があります。

アイコンを使用してシステム認証機能を識別しないこと

システムのTouch ID(拇印)アイコンとFace IDアイコンのようなアイコンが表示された場合、
ユーザーは認証する必要があると考えています。
認証機能を識別するためにアイコンを使用すると、アイコンの違いや大きさの違いなど不整合が生じ、ユーザーを混乱させる場合があります。

データ入力

ドラムロールのようなインターフェイス要素をタップする場合でも、キーボードを使用する場合でも、
情報の入力は面倒なプロセスになる可能性があります。
多くの入力を要求することでプロセスを遅くすると、ユーザーは面倒に感じ、アプリの利用を中断することさえあります。


可能な場合は、選択肢を提示する

データ入力をできるだけ効率的にします。
たとえば、定義済みのオプションのリストから選択する方が応答を入力するより簡単なので、
テキストフィールドの代わりにピッカーまたはテーブルを使用することを検討してください。

可能な限りシステムから情報を取得する

連絡先やカレンダー情報など、自動的に、またはユーザーの許可を得て収集できる情報利用してください。

適切なデフォルト値を指定する

最も可能性の高い値をフィールドに事前入力します。
適切なデフォルトを提供すると、意思決定が最小限に抑えられ、プロセスが高速化します。

必要な値を収集した後でのみ前進を有効にする

[次へ]または[続行]ボタンを有効にする前に、すべての必須フィールドに値があることを確認してください。
ボタンの有効化を、次に進むときの視覚的な合図として使用します。

フィールド値を動的に検証する

長いフォームに記入した後で戻って間違いを修正しなければならないときはイライラします。
なので、可能な限り、次のステップに進む前に正しい値かユーザーに示してください。

目的を伝えるのに役立つヒントをテキストフィールドに表示

テキストフィールドには、空の場合、「Eメール」や「パスワード」などのプレースホルダーテキストを含めることができます。
プレースホルダーテキストで十分な場合は、テキストフィールドの説明に別のラベルを使用しないでください。


ドラッグアンドドロップ

可能な限り、ドラッグアンドドロップを元に戻せるようにしてください。

ユーザーが誤って間違った場所にコンテンツをドロップした場合、ドロップされたコンテンツを削除し、
アプリ内の別の場所から移動した場合は、元の場所に復元する必要があります。

必要に応じて、ドラッグアイテムのプレビューをカスタマイズ

基本的にドラッグされているコンテンツのバックのビューは半透明の表現である必要があります。
この外観はドラッグが進行中であることを示します。

アプリのコンテンツの転送に時間がかかるか、リソースを集中的に使用する場合は、ファイルプロバイダー拡張機能を実装する

ファイルプロバイダー拡張機能が転送プロセスを管理し、アプリが実行されていなくても転送プロセスが完了することを保証します。
転送プロセスは、ユーザーがコンテンツをドロップするまで開始されないことに注意してください。
開発者向けガイダンスについては、NSFileProviderExtensionを参照してください。

アプリのコンテンツの転送に時間が必要な場合は、進捗情報を提供する

コンテンツをダウンロードする必要がある場合や、大きなファイルをコピーするのに時間がかかる場合は、進捗情報を提供します。
少なくとも、コンテンツの合計サイズを指定して、残り時間を計算し、適切な進行状況インジケーターを表示できるようにします。
開発者向けガイダンスについては、NSProgressを参照してください。

強調表示

コンテンツがドラッグされると、ビューが微妙に点滅して色が変化したり、
ドラッグされた画像のためのスペースを空けるために段落が離れたりすることがあります。
逆にコンテンツがドロップされたときは強調表示が削除されていることを確認してください。

フィードバック

フィードバックは、アプリが何をしているかを理解し、次に何ができるかを発見し、アクションの結果を理解するのに役立ちます。

ステータスや他のタイプのフィードバックを控えめに

ユーザーはアクションを実行したり中断したりすることなく、重要な情報を取得できるのが理想です。
たとえば、OS表中のメールアプリは、メッセージのメールボックスをアップデートし最新にしている間、
ステータス情報をツールバーに下部に表示します。
この情報は画面上の主要なコンテンツと競合しませんが、いつでも一目で確認できます。

不要なアラートを減らす

アラートは強力なフィードバックメカニズムですが、ユーザーが不利益になる、もしくはアプリが続行できなくなるような場合にのみ表示するのが理想です。
重要な情報が含まれていないアラートが多すぎると、アラートを無視するようになります。

ファイルの取り扱い

キャンセルまたは削除しない限り、作業は常に保持されるという確信を植え付けると良い

基本的にはファイルを明示的に保存しないでください。
代わりに、ファイルを開いたり閉じたりするとき、および別のアプリに切り替えるときに変更を自動的に保存します。
既存のファイルの編集中など、場合によっては、編集内容が実際にいつキャプチャされたかを確認するために、
保存とキャンセルボタンを明示することが良い場合もあります。

ユーザーがアプリを離れることなくファイルをプレビューできるようにする

クイックルックを使用すると、Keynote、Numbers、Pagesのドキュメント、PDF、画像、およびその他の特定の種類のファイルのコンテンツを
アプリで実際に開かなくても表示できます。

ゲームコントローラー

割愛します

ジェスチャー

原則として、標準のジェスチャーを使用

ゲームなど独自の世界観をもち、没入感をもたらすためのカスタムジェスチャーは推奨されますが、
一般的なアプリでユーザーが意図しているものと違う挙動は行わない方が得策です。

システム全体の画面端のジェスチャーを妨げないこと

面の端のジェスチャーでホーム画面、アプリスイッチャー、通知センター、コントロールセンターにアクセスできます。
ゲームなどで画面端のジェスチャーを使う場合は、最初のスワイプでアプリ固有のジェスチャーが呼び出され、2回目のスワイプでシステムジェスチャーが呼び出されます。
UIViewControllerのpreferredScreenEdgesDeferringSystemGesturesプロパティを参照してください。

標準ジェスチャー

標準ジェスチャー一覧

おそらく大体は知っているジェスチャーでしたが「3本指でつまむ」「3本指でスワイプします。」「シェイク」などあまり親しみのないものもあります。

ハプティクス

ハプティクスは、画面上のインターフェイスとの対話体験を強化するために、人々の触覚に働きかけます。
視覚的、聴覚的なものはもちろん触覚に働きかけることでよりユーザー体験は向上します。

システムハプティクス

スイッチ、スライダー、ピッカーなどの標準のUI要素を使用して、デフォルトでAppleが設計したシステムハプティクスを再生します。

例えば、ピッカーで選択肢を動かしている時。
スクロールするときに軽くたたく感じがします。
このフィードバックは、選択を行ったり確認したりするのではなく、一連の離散値を通じて動きを伝えることを目的としています。
他のものについてはハプティクスのページUIFeedback Generatorなどを参照してください。

カスタムハプティクスパターンの作成

iOS 13以降では、Core Hapticsはカスタムハプティックパターンを生成する2つの基本的なビルディングブロックを提供します。

  • ホーム画面の懐中電灯ボタンをタップするなど、タップや衝動のように感じられる簡潔でコンパクトなエクスペリエンスです。
  • メッセージ内のレーザー効果の経験など、持続的な振動のように感じる連続イベント

カスタムハプティックの生成に選択したビルディングブロックに関係なく、そのシャープネスと強度を制御することもできます。
詳しくはコアハプティクスを参照してください。

NFC(近距離無線通信)

たとえば、ユーザーがおもちゃをスキャンしてビデオゲームに接続したり、
買い物客が店内の看板をスキャンしてクーポンにアクセスしたり。
近距離無線通信(NFC)を使用すると、互いに数センチ以内のデバイスがワイヤレスで情報を交換できます。
タップアンドタッチではなく、スキャンアンドホールドのような用語を使用します。

近距離無線通信は、一部の人には不慣れな場合があります。

親しみやすいものにするために、NFC、コアNFC、近距離無線通信、タグなどの
技術的で開発者向けの用語を参照することは避けてください。
見た目でわかりやすいオブジェクト名にしてください。(WiFiパスワードを共有するためiPhone同士を近づけてくださいなど)

ポインター(iPadOS)

割愛

Undo and Redo

多くのアプリでは、デバイスをシェイクして、入力や削除などの特定の操作を元に戻したりやり直したりできます。
この方法で開始すると、アラートは、元に戻す操作またはやり直し操作を確認またはキャンセルするようにユーザーに要求します。

最後に

part3へ続く...

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

無料のアプリアイコン作成ツール

はじめに

個人開発をする上で、アイコン作りは結構めんどくさい作業だと思っています。外注をしない場合は自分で作るしかありません。
そこで、個人的に使い心地がよかったツールを紹介します。ただし、この記事内では詳しい使い方に関しては説明していません。ご了承ください。

1. 元になる画像を作るツール

Pixlrが個人的にオススメです。ブラウザで動くのでダウンロードする必要もありませんし、無料でも使えます。
https://pixlr.com/jp/
背景を塗りつぶして、フリー素材のアイコンを貼り付ける程度の簡単な作業であれば問題なくできました。テキストの挿入もできるようです。

2. 作った画像からアイコンを作成するツール

https://makeappicon.com/
このツールは1枚の画像から、アイコンに必要な画像を作成してくれます。作成した画像はメールで送られてきます。

以上です。あとはアプリ側に送られてきた画像をアイコンとして登録してください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[2020年9月11日] App Storeレビュー・ガイドラインのアップデート

2020年9月11日にApp Storeのレビュー・ガイドラインが更新されました。

詳細は App Store Review Guidelines で確認 1 するとして、ひとまず概要をざっと把握したい方のために、上記の発表内容を日本語訳 2 してみました。

App Storeのレビュー・ガイドラインが更新されました

App Storeはお客様がアプリを発見したりダウンロードするための安全で信頼できる場所であり、同時に開発者にとって絶好の機会を得られる場でもあります。以下のガイドラインの変更と明確化は、今後リリースされるOSの新機能をサポートし、お客様をより保護して、アプリのレビュー・プロセスをできるかぎりスムーズに進めることを手助けします。

アップデートの内容は以下のとおりです。完全な内容については App Store Review Guidelines をご覧ください。

ガイドラインの変更

2.5.16: App Clips、ウィジェット、エクステンション、および通知はアプリのコンテンツと機能に関連している必要があります。さらに、App Clipを含むすべての機能はメイン・アプリのバイナリに含まれている必要があります。App Clipsには広告を含めることができません。

3.1.2(a): ストリーミング・ゲーム・サービスの定期購読として提供されるゲームはApp Storeから直接ダウンロードしなければならず、また購読者による重複支払いを避けるように設計されていなければならず、購読者以外のユーザーに不利益を与えてはなりません。

3.1.2(a): Appleの事前承認を得て音楽やビデオ購読の自動更新を提供するアプリは、携帯電話キャリアのアプリ内で提供されているデータ・プランとの事前定義されたバンドルに含まれている可能性があります。

3.1.3(a): リーダー・アプリは無料枠向けのアカウント作成機能や、既存ユーザー向けのアカウント管理機能を提供する場合があります。

3.1.3(d): 個人間の体験: アプリにおいて2人の個人間のリアルタイム体験(例: 生徒の指導、医療相談、不動産内見、フィットネス・トレーニングなど)を購入できる場合、それらの支払いにアプリ内課金以外の決済方法を利用することができます。1人と数人、または1人と多数のリアルタイム体験についてはアプリ内課金を使用する必要があります。

3.1.3(f): 無料のスタンドアロン・アプリ: 有料のWebベース・ツール(例: VOIP、クラウド・ストレージ、電子メール・サービス、Webホスティング)のスタンドアロン・コンパニオンとして機能する無料アプリは、アプリ内での購入やアプリ外での購入アクションがない場合、アプリ内課金を使用する必要はありません。

3.1.7: ディスプレイ広告はメイン・アプリの実行ファイルに限定されるべきであり、エクステンション、App Clips、ウィジェット、通知、キーボード、watchOSアプリなどには含めるべきではありません。

3.2.2(vi): アプリはその機能やコンテンツへのアクセス、アプリ自体の利用、金銭的またはその他の報酬(ギフトカードやコード、またはそれ以外)をユーザーが得るために、アプリの評価やレビュー、動画の視聴、他アプリのダウンロード、広告のタップ、広告トラッキングの有効化、その他の類似の行動をユーザーに要求してはなりません。

3.2.2(x): 個人向けローンを提供するアプリは、同等の最大年率(APR)と支払期限を含むがこれらに限定されないすべてのローン条件を、明確かつ目立つように開示しなければなりません。アプリは、費用や手数料を含め、最大年率(APR)を36%より高く設定してはならず、60日以内に全額返済を要求してはなりません。

4.9: ストリーミング・ゲームは、すべてのガイドラインを遵守するかぎり許可されています。例えば、すべてのゲーム・アップデートはレビューのために提出されなければならず、開発者は検索のための適切なメタデータを提供しなければならず、ゲームは機能をアンロックするためにアプリ内課金を提供しなければなりません。もちろん、App Store外のすべてのユーザーにリーチするため、オープンなインターネットやWebブラウザ・アプリが常に存在します。

4.9.1: 個々のストリーミング・ゲームは、App Storeの製品ページがあること、ランキングや検索結果に表示されること、ユーザーによる評価やレビューがあること、ScreenTimeや他のペアレンタル・コントロール・アプリで管理できること、ユーザーのデバイスに表示されることなどを考慮して、App Storeに提出される必要があります。

4.9.2: ストリーミング・ゲーム・サービスは、ユーザーがサービスにサインアップしてApp Storeでゲームをみつけるのに役立つカタログアプリをApp Storeで提供することができます。この場合、アプリがユーザーにアプリ内課金による定期購読の支払い方法を提供したり、Sign in with Appleを使用したりするなど、すべてのガイドラインを遵守していることが条件となります。カタログアプリに含まれるすべてのゲームは、App Storeの個別製品ページにリンクしている必要があります。

提出したあと: それでもレビューの結果に納得できない場合や、ガイドライン自体の変更を提案したい場合は、不服申し立てを提出してください。

バグ修正版の提出: App Storeに登録されている既存アプリについては、法的問題に関連するものを除いて、ガイドライン違反を理由にバグ修正版のレビューが遅れることはありません。アプリがリジェクトされ、このプロセスの対象になっている場合は、 問題解決センター を使用して、このプロセスを利用したい旨をApp Reviewチームに直接連絡し、次回の提出で問題を解決する予定であることを伝えてください。

ガイドラインの明確化

2.3.1: アプリに隠し機能、休止機能、またはドキュメントに載っていない機能を含めないでください。アプリの機能は、エンドユーザーやApp Reviewチームにわかりやすく提供されるべきです。

2.3.1: すべての新機能やプロダクトの変更は、App Store Connectの App Reviewに関する情報 セクションにある メモ に具体的に記述され、レビューのために利用可能になっている必要があります。

2.3.7: ユニークなアプリ名を選択し、アプリを正確に説明するキーワードを割り当ててください。システムの抜け穴を利用するために、商標登録されたキーワードや人気アプリの名前、価格情報 3 、その他の無関係なフレーズをメタデータに詰め込もうとしないでください。

3.1.3: その他の購入方法: 以下のアプリはアプリ内課金以外の購入方法を使用することができます。このセクションのアプリでは、アプリ内で、またはアプリ内のアカウント登録で取得した連絡先(電子メールやテキスト・メッセージなど)に送信される通信を通じて、ユーザーにアプリ内課金以外の購入方法の利用を促すことはできません。

3.1.3(c): エンタープライズ・サービス: アプリを組織やグループの従業員や生徒に直接販売する場合(例: 専門的なデータベースや教室管理ツールなど)、アプリ内課金に加えて別の購入方法でもそれらの支払いを回収することができます。消費者向け、シングル・ユーザー向け、または家族向けの販売では、アプリ内課金を使用する必要があります。

3.1.3(e): 旧 3.1.5(a) の番号を変更しました。

3.1.3(b): マルチプラットフォーム・サービス: 複数のプラットフォームで動作するアプリでは、マルチプラットフォーム・ゲームの 消耗型 アイテムを含め、ユーザーがアプリ内で取得したコンテンツ、購読、または機能に他のプラットフォームやWebサイトからアクセスできる場合があります。

3.1.5: 旧 3.1.5(b) の番号を変更しました。

4.5.2(i): iOSのMusicKitを使えば、Apple Musicとそのローカル・ミュージック・ライブラリを、あなたのアプリやゲームからネイティブに再生することができます。ユーザーがApple Musicアカウントに許可を与えると、あなたのアプリでプレイリストを作成したり、曲をライブラリに追加したり、Apple Musicのカタログにある何百万もの曲を再生したりすることができます。

5.1.2(vi): HomeKit API、HealthKit、Clinical Health Records API、MovementDisorder APIs、ClassKitまたは深度および/または顔のマッピング・ツール(例: ARKit、Camera APIs、Photo APIsなど)から収集したデータは、第三者によるものを含め、マーケティング、広告、またはUse-basedなデータ・マイニングのために使用することはできません。CallKit、HealthKit、ClassKit、およびARKitを実装するためのベストプラクティスを学びましょう。


  1. 本記事執筆時点で、日本語版のApp Store Reviewガイドライン最終更新日:2020年3月4日 となっています 

  2. 一部不自然な表現や意訳も入っていますので、正確で完全な内容については App Store Review Guidelines を参照してください 

  3. "無料" など価格についての表現 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS で 画像の横を画面ギリギリまで広げて、高さをアスペクト比で伸ばした画像にする方法

やりたいこと

  • 端末毎に横サイズが異なるので、横幅を固定値で指定したくない
    • 左右マージン20pxとかにしたい
  • 高さはアスペクト比維持していい感じに伸びて欲しい
  • 画像のアスペクト比は崩さないで欲しい

結論

  • 左右に20pxのマージン制約つける
  • 画像にアスペクト比の制約をつけて、画像毎のアスペクト比を指定する
  • content mode は scale to fit にする

蛇足. 試したけどダメだったこと

左右制約 と content mode を aspect fit にする
-> 端末サイズによって横幅が広がりきらない

左右制約と content mode を scale to fit にする
-> 画像アスペクト比が維持されないで崩れる

Android だったら wrap_content 指定するだけなのにね。iOSは大変だ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Xcodeの「Please reconnect the device.」の解決方法

実機のOSのバージョンとXcodeのバージョンばあっていない時に、発生するエラー。わかりにくいです!!

対応方法リスト

  1. Xcodeをアップデートする
  2. 現在のXcodeのバージョンに、実機のiOSに対応するDevice Supportを突っ込む(ここら辺が参考になる)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Human Interface Guidelinesオレオレ翻訳part1

はじめに

最初に言っておきます。わかりにくいかも。ごめんて。
内容は他で参考になったものを入れつつ自分なりに意訳してるとこもあります。
デザインテーマと設計原則はできるだけ一行くらいで説明するように努力してます。

デザインテーマ

明快さ

デザインの重点は機能性。スペース、色、フォント、グラフィックスをシンプルに。

尊敬

コンテンツが引き立つようにベゼル、グラデーション、ドロップシャドウの使用を最小限に。

奥行き

モーダルやプッシュの使い分けによって機能へのアクセスや探索の補助を行う。


設計原則

6つの設計原則が設定されています。
他のUIについての本でも書かれているような、特に重要なものに星を振りました。

美的整合性

アプリに準じたUI/UXを意識する。
基本は機能を分かりやすくする装飾にするべきであり、ゲームは没入感をますように世界観を提示する。

★一貫性

統一された色分け、規則性のある遷移、馴染みのあるアイコンなどを利用しユーザーが想定しているものを影響するべき。

直接操作

スワイプやタップによるジェスチャーを取り入れることによって、直感的な操作をユーザーに体験させる。

★メタファー

現実世界のオブジェクトや出っ張って見えるものは押せそうなど認識し慣れているものを利用する。
(ただ現実のものをそのまま使うより、想像現実を利用することでUXが上がることもある)

★フィードバック

アニメーションとサウンド、実行時のハイライトなどアクションに対してのフィードバックを起こすことで何をしているか認識させる。

★ユーザーコントロール

アプリが処理を実行するのではなく、ユーザーのアクションによって自由に使えるような設計が好ましい。


インターフェース概要

ほとんどのiOSアプリ開発ではUIkitフレームワークを利用します。
カスタマイズして使用されますが、根源的な外観・処理に一貫性があることでどのiOSデバイスでも単一の良いアプリが設計できます。
UIKitが提供するインターフェースには大きく3つカテゴリがあります。

Bar

いわゆるナビゲーションバー。
画面の階層を知らせるのに役にたったり、共通で操作させたいアクションなどを含めることができます。

View

実際に操作する画面。
テキストや画像、アニメーションのようなアプリのコンテンツを提供します。

Control

ボタンやスイッチ、テキストフィールドのようなインタラクティブな操作を提供します。

アプリのアーキテクチャ

起動

起動体験はユーザーの心理に大きく影響します。
デバイスの性能や使用頻度によらず、起動は早くなくてはいけないです。

楽しく、違和感のない起動体験の設計をするには以下の要素が重要です。

起動画面の提供

いわゆるスプラッシュ画面。
スプラッシュ画面を表示する意図は、最初のコンテンツの読み込みを可能にしながら、アプリが高速で応答性が高いという印象をユーザーに与えるためです。

適切な方向で起動

アプリの縦向き横向きを判定して適切に表示する必要があります。
SplitViewなども出てきたのでそちらの対応も必要です。

起動後に必要な権限要求をする

ユーザーがアプリを開いたときに情報を提供するように求め、後でアプリの設定で変更できるようにします。
アプリ起動時もですが、位置情報などは必要な画面でダイアログを出すなども検討が必要だと思います。

アプリ内にライセンス契約や免責事項を表示しない

基本はApp Storeに同意書と免責事項はダウンロードする前にユーザーが確認できるようにする必要があります。
アプリに含める必要がある場合はUXを損なわないような設計をします。

アプリの再起動時に以前の状態を復元

アプリキル、バックグラウンド移行からの起動は適切な画面を表示させる必要があります。

再起動を勧めない

再起動には時間がかかり、アプリの信頼性が低く、使いにくいように見えてしまいます。

リリース後すぐに、もしくは頻繁にアプリの評価を依頼しないこと

当たり前ですが、最初のリリース後すぐに、またはユーザーがアプリを使用している間に頻繁に評価を求めるのは煩わしく、正しいフィードバックがさない可能性があります。
決して人々にあなたのアプリを評価することを強制しないでください。

オンボーディング

※いわゆるウォークスルーやコーチマークなどです。

  • ライセンスの詳細やセットアップの仕方を載せない
  • スキップできる機能をつける
  • ヘルプが必要な適切なタイミングを予測する
  • 多くのチュートリアルが必要な場合アプリのUIを見直す必要がある
  • 指示をするよりも実行して学んでもらうことが1番

ローディング

アプリがフリーズしたように見えるとユーザーがアプリを離れる可能性が高くなるので、ローディングを適切に入れる必要があります。

loading_2x.png

ロード時間を明確に示す

少なくとも、何かが起こっていることを伝えるアクティビティスピナーを表示します。

できるだけ早くコンテンツを表示する

プレースホルダーテキスト、グラフィックなどを使用して、コンテンツがまだ利用できない場所を特定します。

読み込み時間を楽しませるよう工夫する

ゲームプレイ、面白いビデオシーケンスなどで読み込み時間を有効に活用させます。

ロードのカスタマイズ

アプリやゲームのスタイルに合わせてより世界観に没入できる体験を提供できないか検討必要です。

※別の記事でネイティブアプリに関わらず、6秒未満の待ち時間がある場合はローディングダイアログ(スクリーン)を、7秒以上の場合はプログレスバーを表示させると良いとありました。もちろんケースバイケースです。

モーダリティ

アラートビューやモーダルビューがこれに相当します。

同じコンテキストで一時的に別の操作を終了するために明示的なアクションを必要とする設計手法です。

iOS13以降ではシートと全画面表示の2種類があります。

シート

シートプレゼンテーションスタイルは、メインのコンテンツの上に表示し、カバーされていない領域をすべて淡色表示して、それらとの相互作用を防ぐカードとして表示されます。

親ビューまたは前のカードの上端は、現在のカードの後ろに表示され、
カードを開いたときに中断したタスクを覚えやすくします。

画面を閉じるアクションとして
- 画面の上端から下にスワイプ
- コンテンツがMaxYの状態で画面を下にスワイプ
- ボタンをタップする
複雑なタスクを有効にしない非没入型のモーダルコンテンツのシートを使用します。

全画面表示(Full Screen)

全画面表示スタイルは画面全体をカバーします。
前のビューは完全に覆われ、視覚的な散漫が最小限に抑えられます。
人々はボタンをタップして全画面のモーダルビューを閉じます。

ビデオ、写真、カメラビューなどの没入型コンテンツ、
または写真の編集などのフルスクリーンプレゼンテーションのメリットを活用する複雑なタスクには、フルスクリーンのモーダルビューを使用します。

モダリティの必要性

異なるタスクを選択または実行することに人々の注意を集中させることが重要である場合に使用する。
モーダルは、メインコンテンツから外し、中断アクションを求めるので、
明確な利点を提供する場合にのみ使用することが不可欠です。

モーダルに閉じるボタンを常に含める

たとえば、「完了」または「キャンセル」を使用できます。

閉じる前に確認をとる

何かしらのアクションによってユーザー生成コンテンツが失われる可能性がある場合は、状況を説明し、解決方法を示すアクションシートを提示します。

基本的に、モーダル識別するタイトルを表示

モーダルタスクに入ると、以前のコンテキストから切り替わるので、
新しいコンテキストを明確にすることがお勧めされています。

モーダルビューの外観をアプリと調整する

たとえば、モーダルビューにナビゲーションバーが含まれている場合、アプリのナビゲーションバーと同じ外観を使用する必要があります。

ナビゲーション

ユーザーは自分の期待している機能や画面にアクセスできない状態にならないとナビゲーションに気づかない傾向にあります。
ナビゲーションは自然で親しみやすくアプリの構造と目的をサポートする役割に徹するべきです。

iOSには、3つの主要なナビゲーションスタイルがあります。

  • 階層的ナビゲーション

目的地に到着するまで、画面ごとに1つの選択を行います。
別の目的地に移動するには、手順をたどるか、最初からやり直して別の選択をする必要があります。
設定とメールはこのナビゲーションスタイルを使用します。

  • フラットナビゲーション

複数のコンテンツカテゴリを切り替えます。
音楽とApp Storeはこのナビゲーションスタイルを使用します。

  • コンテンツ主導またはエクスペリエンス主導のナビゲーション

コンテンツ内を自由に移動するか、コンテンツ自体がナビゲーションを定義します。ゲーム、書籍、その他の没入型アプリは通常、このナビゲーションスタイルを使用します。

常に明確なパスを提供

アプリ内のどこにいるか、次の目的地への行き方を常に知っておく必要があります。
ナビゲーションスタイルに関係なく、簡単にたどることが不可欠です。
一般に、各画面へのパスは1つにしてください。
複数のコンテキストで特定の画面を表示したい場合は、
- アクションシート
- アラート
- ポップオーバー、またはモーダルビュー
の使用を検討してください。

すばやく簡単にコンテンツにアクセスできる情報構造を設計すること

最小数のタップ、スワイプ、および画面を必要とする方法で情報構造を整理するべきです

タッチジェスチャーを活用する

スワイプを利用すれば簡単に移動できます。

たとえば、画面の横からスワイプして前の画面に戻ることができます。

標準のナビゲーションコンポーネントを使用する

可能な限り、ページコントロール、タブバー、セグメント化されたコントロール、テーブルビュー、コレクションビュー、分割ビューなど標準のナビゲーションコントロールを使用してください。
ユーザーはこれらのコントロールに慣れており、アプリの操作方法を直感的に理解できます。

ナビゲーションバーを使用して、データの階層を移動する

ナビゲーションバーのタイトルには、階層内の現在の位置を表示できます。
[戻る]ボタンを使用すると、前の場所に簡単に戻ることができます。

タブバーを使用して、コンテンツまたは機能のピアカテゴリを表示します。

タブバーを使用すると、現在の場所に関係なく、カテゴリをすばやく簡単に切り替えることができます。

iPadでは、タブバーの代わりに分割ビューを使用する

分割ビューは、タブバーと同じクイックナビゲーションを提供すると同時に、大きなディスプレイをより有効に活用することができます。

ページコントロール

同じタイプのコンテンツの複数のページがある場合は、ページコントロールを使用します。
ページコントロールは、使用可能なページ数と現在アクティブなページを明確に伝えます。

※個人的にはページコントロールは不要だと思っています。(チュートリアルなど慣れている部分で使うのは良いと思う)
後ろのViewの色などによって目立たない、というかそもそも小さくて目立たないので、
スクロールができることを示すのに十分ではないです。
代替として、画面端に矢印をおいたりセグメントを置くなどがあります。

守ってはいけないiOSデザインとしてこちらにまとめられています。
https://u-site.jp/alertbox/4-ios-rules-break

許可の要求

ユーザーは、アプリが現在の場所、カレンダー、連絡先情報、リマインダー、写真などの
個人情報にアクセスすることを許可する必要があります。
個人情報の利用はユーザーにとって利便性のある機能の提供に限り、基本的に企業側の営利目的で使用することはできません。

※利用の仕方によってはリジェクト対象になるので気をつける必要があります。(実際に位置情報の利用などでありました。)

アプリに情報が必要な理由を説明してください。

システムの権限要求アラートに情報が必要な理由を載せます。
テキストは短く具体的なものにし、文の大文字小文字を使用し、礼儀正しくして、
人々がプレッシャーを感じないようにします。アプリ名を含める必要はありません。

例)
【OK】アプリは、いびき音を検出するために夜間にあなたを記録します。
【NG】より良い体験のためにマイクへのアクセスが必要です。
【NG】マイクへのアクセスをオンにします。

アプリが機能するために必要な場合にのみ、起動時に権限をリクエスト

アプリの操作が個人情報に依存していることが明らかな場合、ユーザーはこのリクエストに悩まされることはありません。

不必要に位置情報を要求しない

位置情報にアクセスする前に、システムをチェックして、位置情報サービスが有効になっているかどうかを確認してください。
この知識があれば、機能で本当に必要になるまでアラートを遅らせたり、アラートを完全に回避したりできます。

設定

一部のアプリは設定機能を提供する必要があります。
ただ、ほとんどのユーザーにとって想定どおりの動きになるようアプリを設計すれば
設定の必要性を減らす事ができます。

可能な限りシステムへ問い合わせる

例えばユーザーに直接住所を入力させるのではなく、現在地情報を取得する許可をシステム側に問い合わせることで
余計な設定の手間を省くことができます。
もし、ユーザーがシステムからの許可を拒否した場合は手入力させます。

優先順位をつける

一次階層にはメインとなる設定を、あまり利用しないものは二次改装にするなど工夫をします。

頻繁に変更されない構成オプションを[設定]で公開

OSの設定アプリは、システム全体で構成を変更するための中心的な場所ですが、
そこに到達するにはアプリを離れる必要があります。
なので、できるだけアプリ内で直接設定を調整する方がはるかに便利です。
もしくはその画面へのショートカットスキーマがあれば、利用し誘導することも可能です。

 最後に

part2へ続く...

翻訳元
Human Interface Guidelines

画像引用先:
https://developer.apple.com/design/human-interface-guidelines/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Human Interface Guidelines part1

はじめに

最初に言っておきます。わかりにくいかも。ごめんて。
内容は他で参考になったものを入れつつ自分なりに意訳してるとこもあります。
デザインテーマと設計原則はできるだけ一行くらいで説明するように努力してます。

デザインテーマ

明快さ

デザインの重点は機能性。スペース、色、フォント、グラフィックスをシンプルに。

尊敬

コンテンツが引き立つようにベゼル、グラデーション、ドロップシャドウの使用を最小限に。

奥行き

モーダルやプッシュの使い分けによって機能へのアクセスや探索の補助を行う。


設計原則

6つの設計原則が設定されています。
他のUIについての本でも書かれているような、特に重要なものに星を振りました。

美的整合性

アプリに準じたUI/UXを意識する。
基本は機能を分かりやすくする装飾にするべきであり、ゲームは没入感をますように世界観を提示する。

★一貫性

統一された色分け、規則性のある遷移、馴染みのあるアイコンなどを利用しユーザーが想定しているものを影響するべき。

直接操作

スワイプやタップによるジェスチャーを取り入れることによって、直感的な操作をユーザーに体験させる。

★メタファー

現実世界のオブジェクトや出っ張って見えるものは押せそうなど認識し慣れているものを利用する。
(ただ現実のものをそのまま使うより、想像現実を利用することでUXが上がることもある)

★フィードバック

アニメーションとサウンド、実行時のハイライトなどアクションに対してのフィードバックを起こすことで何をしているか認識させる。

★ユーザーコントロール

アプリが処理を実行するのではなく、ユーザーのアクションによって自由に使えるような設計が好ましい。


インターフェース概要

ほとんどのiOSアプリ開発ではUIkitフレームワークを利用します。
カスタマイズして使用されますが、根源的な外観・処理に一貫性があることでどのiOSデバイスでも単一の良いアプリが設計できます。
UIKitが提供するインターフェースには大きく3つカテゴリがあります。

Bar

いわゆるナビゲーションバー。
画面の階層を知らせるのに役にたったり、共通で操作させたいアクションなどを含めることができます。

View

実際に操作する画面。
テキストや画像、アニメーションのようなアプリのコンテンツを提供します。

Control

ボタンやスイッチ、テキストフィールドのようなインタラクティブな操作を提供します。

アプリのアーキテクチャ

起動

起動体験はユーザーの心理に大きく影響します。
デバイスの性能や使用頻度によらず、起動は早くなくてはいけないです。

楽しく、違和感のない起動体験の設計をするには以下の要素が重要です。

起動画面の提供

いわゆるスプラッシュ画面。
スプラッシュ画面を表示する意図は、最初のコンテンツの読み込みを可能にしながら、アプリが高速で応答性が高いという印象をユーザーに与えるためです。

適切な方向で起動

アプリの縦向き横向きを判定して適切に表示する必要があります。
SplitViewなども出てきたのでそちらの対応も必要です。

起動後に必要な権限要求をする

ユーザーがアプリを開いたときに情報を提供するように求め、後でアプリの設定で変更できるようにします。
アプリ起動時もですが、位置情報などは必要な画面でダイアログを出すなども検討が必要だと思います。

アプリ内にライセンス契約や免責事項を表示しない

基本はApp Storeに同意書と免責事項はダウンロードする前にユーザーが確認できるようにする必要があります。
アプリに含める必要がある場合はUXを損なわないような設計をします。

アプリの再起動時に以前の状態を復元

アプリキル、バックグラウンド移行からの起動は適切な画面を表示させる必要があります。

再起動を勧めない

再起動には時間がかかり、アプリの信頼性が低く、使いにくいように見えてしまいます。

リリース後すぐに、もしくは頻繁にアプリの評価を依頼しないこと

当たり前ですが、最初のリリース後すぐに、またはユーザーがアプリを使用している間に頻繁に評価を求めるのは煩わしく、正しいフィードバックがさない可能性があります。
決して人々にあなたのアプリを評価することを強制しないでください。

オンボーディング

※いわゆるウォークスルーやコーチマークなどです。

  • ライセンスの詳細やセットアップの仕方を載せない
  • スキップできる機能をつける
  • ヘルプが必要な適切なタイミングを予測する
  • 多くのチュートリアルが必要な場合アプリのUIを見直す必要がある
  • 指示をするよりも実行して学んでもらうことが1番

ローディング

アプリがフリーズしたように見えるとユーザーがアプリを離れる可能性が高くなるので、ローディングを適切に入れる必要があります。

loading_2x.png

ロード時間を明確に示す

少なくとも、何かが起こっていることを伝えるアクティビティスピナーを表示します。

できるだけ早くコンテンツを表示する

プレースホルダーテキスト、グラフィックなどを使用して、コンテンツがまだ利用できない場所を特定します。

読み込み時間を楽しませるよう工夫する

ゲームプレイ、面白いビデオシーケンスなどで読み込み時間を有効に活用させます。

ロードのカスタマイズ

アプリやゲームのスタイルに合わせてより世界観に没入できる体験を提供できないか検討必要です。

※別の記事でネイティブアプリに関わらず、6秒未満の待ち時間がある場合はローディングダイアログ(スクリーン)を、7秒以上の場合はプログレスバーを表示させると良いとありました。もちろんケースバイケースです。

モーダリティ

アラートビューやモーダルビューがこれに相当します。

同じコンテキストで一時的に別の操作を終了するために明示的なアクションを必要とする設計手法です。

iOS13以降ではシートと全画面表示の2種類があります。

シート

シートプレゼンテーションスタイルは、メインのコンテンツの上に表示し、カバーされていない領域をすべて淡色表示して、それらとの相互作用を防ぐカードとして表示されます。

親ビューまたは前のカードの上端は、現在のカードの後ろに表示され、
カードを開いたときに中断したタスクを覚えやすくします。

画面を閉じるアクションとして
- 画面の上端から下にスワイプ
- コンテンツがMaxYの状態で画面を下にスワイプ
- ボタンをタップする
複雑なタスクを有効にしない非没入型のモーダルコンテンツのシートを使用します。

全画面表示(Full Screen)

全画面表示スタイルは画面全体をカバーします。
前のビューは完全に覆われ、視覚的な散漫が最小限に抑えられます。
人々はボタンをタップして全画面のモーダルビューを閉じます。

ビデオ、写真、カメラビューなどの没入型コンテンツ、
または写真の編集などのフルスクリーンプレゼンテーションのメリットを活用する複雑なタスクには、フルスクリーンのモーダルビューを使用します。

モダリティの必要性

異なるタスクを選択または実行することに人々の注意を集中させることが重要である場合に使用する。
モーダルは、メインコンテンツから外し、中断アクションを求めるので、
明確な利点を提供する場合にのみ使用することが不可欠です。

モーダルに閉じるボタンを常に含める

たとえば、「完了」または「キャンセル」を使用できます。

閉じる前に確認をとる

何かしらのアクションによってユーザー生成コンテンツが失われる可能性がある場合は、状況を説明し、解決方法を示すアクションシートを提示します。

基本的に、モーダル識別するタイトルを表示

モーダルタスクに入ると、以前のコンテキストから切り替わるので、
新しいコンテキストを明確にすることがお勧めされています。

モーダルビューの外観をアプリと調整する

たとえば、モーダルビューにナビゲーションバーが含まれている場合、アプリのナビゲーションバーと同じ外観を使用する必要があります。

ナビゲーション

ユーザーは自分の期待している機能や画面にアクセスできない状態にならないとナビゲーションに気づかない傾向にあります。
ナビゲーションは自然で親しみやすくアプリの構造と目的をサポートする役割に徹するべきです。

iOSには、3つの主要なナビゲーションスタイルがあります。

  • 階層的ナビゲーション

目的地に到着するまで、画面ごとに1つの選択を行います。
別の目的地に移動するには、手順をたどるか、最初からやり直して別の選択をする必要があります。
設定とメールはこのナビゲーションスタイルを使用します。

  • フラットナビゲーション

複数のコンテンツカテゴリを切り替えます。
音楽とApp Storeはこのナビゲーションスタイルを使用します。

  • コンテンツ主導またはエクスペリエンス主導のナビゲーション

コンテンツ内を自由に移動するか、コンテンツ自体がナビゲーションを定義します。ゲーム、書籍、その他の没入型アプリは通常、このナビゲーションスタイルを使用します。

常に明確なパスを提供

アプリ内のどこにいるか、次の目的地への行き方を常に知っておく必要があります。
ナビゲーションスタイルに関係なく、簡単にたどることが不可欠です。
一般に、各画面へのパスは1つにしてください。
複数のコンテキストで特定の画面を表示したい場合は、
- アクションシート
- アラート
- ポップオーバー、またはモーダルビュー
の使用を検討してください。

すばやく簡単にコンテンツにアクセスできる情報構造を設計すること

最小数のタップ、スワイプ、および画面を必要とする方法で情報構造を整理するべきです

タッチジェスチャーを活用する

スワイプを利用すれば簡単に移動できます。

たとえば、画面の横からスワイプして前の画面に戻ることができます。

標準のナビゲーションコンポーネントを使用する

可能な限り、ページコントロール、タブバー、セグメント化されたコントロール、テーブルビュー、コレクションビュー、分割ビューなど標準のナビゲーションコントロールを使用してください。
ユーザーはこれらのコントロールに慣れており、アプリの操作方法を直感的に理解できます。

ナビゲーションバーを使用して、データの階層を移動する

ナビゲーションバーのタイトルには、階層内の現在の位置を表示できます。
[戻る]ボタンを使用すると、前の場所に簡単に戻ることができます。

タブバーを使用して、コンテンツまたは機能のピアカテゴリを表示します。

タブバーを使用すると、現在の場所に関係なく、カテゴリをすばやく簡単に切り替えることができます。

iPadでは、タブバーの代わりに分割ビューを使用する

分割ビューは、タブバーと同じクイックナビゲーションを提供すると同時に、大きなディスプレイをより有効に活用することができます。

ページコントロール

同じタイプのコンテンツの複数のページがある場合は、ページコントロールを使用します。
ページコントロールは、使用可能なページ数と現在アクティブなページを明確に伝えます。

※個人的にはページコントロールは不要だと思っています。(チュートリアルなど慣れている部分で使うのは良いと思う)
後ろのViewの色などによって目立たない、というかそもそも小さくて目立たないので、
スクロールができることを示すのに十分ではないです。
代替として、画面端に矢印をおいたりセグメントを置くなどがあります。

守ってはいけないiOSデザインとしてこちらにまとめられています。
https://u-site.jp/alertbox/4-ios-rules-break

許可の要求

ユーザーは、アプリが現在の場所、カレンダー、連絡先情報、リマインダー、写真などの
個人情報にアクセスすることを許可する必要があります。
個人情報の利用はユーザーにとって利便性のある機能の提供に限り、基本的に企業側の営利目的で使用することはできません。

※利用の仕方によってはリジェクト対象になるので気をつける必要があります。(実際に位置情報の利用などでありました。)

アプリに情報が必要な理由を説明してください。

システムの権限要求アラートに情報が必要な理由を載せます。
テキストは短く具体的なものにし、文の大文字小文字を使用し、礼儀正しくして、
人々がプレッシャーを感じないようにします。アプリ名を含める必要はありません。

例)
【OK】アプリは、いびき音を検出するために夜間にあなたを記録します。
【NG】より良い体験のためにマイクへのアクセスが必要です。
【NG】マイクへのアクセスをオンにします。

アプリが機能するために必要な場合にのみ、起動時に権限をリクエスト

アプリの操作が個人情報に依存していることが明らかな場合、ユーザーはこのリクエストに悩まされることはありません。

不必要に位置情報を要求しない

位置情報にアクセスする前に、システムをチェックして、位置情報サービスが有効になっているかどうかを確認してください。
この知識があれば、機能で本当に必要になるまでアラートを遅らせたり、アラートを完全に回避したりできます。

設定

一部のアプリは設定機能を提供する必要があります。
ただ、ほとんどのユーザーにとって想定どおりの動きになるようアプリを設計すれば
設定の必要性を減らす事ができます。

可能な限りシステムへ問い合わせる

例えばユーザーに直接住所を入力させるのではなく、現在地情報を取得する許可をシステム側に問い合わせることで
余計な設定の手間を省くことができます。
もし、ユーザーがシステムからの許可を拒否した場合は手入力させます。

優先順位をつける

一次階層にはメインとなる設定を、あまり利用しないものは二次改装にするなど工夫をします。

頻繁に変更されない構成オプションを[設定]で公開

OSの設定アプリは、システム全体で構成を変更するための中心的な場所ですが、
そこに到達するにはアプリを離れる必要があります。
なので、できるだけアプリ内で直接設定を調整する方がはるかに便利です。
もしくはその画面へのショートカットスキーマがあれば、利用し誘導することも可能です。

 最後に

part2へ続く...

翻訳元
Human Interface Guidelines

画像引用先:
https://developer.apple.com/design/human-interface-guidelines/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む