ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
進化するキーボードの最新情報
キーボードは毎年進化し、サポートする言語、サイズ、対応機能の範囲も拡大しています。 デバイス上でどのように表示されるかに関係なく、キーボードに合わせてアプリをデザインする方法を紹介します。 スムーズなテキスト入力を提供する方法と、システム内でキーボードがどのように機能するかを理解するのに役立つ、重要なアーキテクチャ上の変更も共有します。
関連する章
- 0:00 - Introduction
- 1:29 - Out of process keyboard
- 3:47 - Design for the keyboard
- 14:06 - New text entry APIs
- 15:06 - Key takeaways
リソース
- Adding a search interface to your app
- Adjusting your layout with keyboard layout guide
- FocusState
- Human Interface Guidelines: Keyboards
- SafeAreaRegions
関連ビデオ
WWDC23
WWDC21
-
ダウンロード
♪ ♪
みなさん こんにちは Spencer Lewsonです 今日はここ数年で キーボードがどのように進化したかについて お話したいと思います そしてこれらの進化にあった アプリのデザイン方法についても説明します
ご存知の通りiPhoneのキーボードは 2007年に初めて導入され それ以来 大幅に進化しています 現在 多くの異なる言語が サポートされており それぞれの言語でレイアウトのサイズが 異なる場合があります そして もちろんキーボードは 様々なデバイスにも搭載されています キーボードと同じようにシステムも進化し マルチタスクやフローティングキーボード等 エキサイティングな新機能が追加され キーボードがアプリの境界を 超えることができるようになりました
昨年iPadで まったく新しいレベルの生産性を実現する ステージマネージャを導入しました 複数のシーンが複数のディスプレイで 実行されるようになったことで ハードウェアキーボードとマウスの使用が これまで以上に魅力的になりました 今日はキーボードの再構築によって 様々なキーボードのシナリオを どのように可能にするかと それがアプリに与える影響について 説明します また キーボードと シームレスに動作するように できるだけ少ない労力で アプリをデザインするヒントやテクニックも いくつか共有したいと思います 最後にテキスト入力の世界で いくつかのエキサイティングな新機能を 紹介したいと思います では 新しいアウトプロセスの キーボードについて話しましょう
アプリからキーボードを取り除くことで セキュリティを向上させ ユーザーが入力した内容の プライバシーを確保できます キーボードが単一になったことで 複数のアプリで複数のインスタンスを 実行する必要がなくなり アプリとシステム全体の メモリが解放されます この新しい構造により未来思考のデザインと エキサイティングな新機能の実装が 可能になります では どのように機能するか 少し説明しましょう iOS17以前は キーボードのビューとロジックは アプリのプロセス内で実行されていました iOS17のiPhoneでは キーボードが独自のプロセスに移動され ほぼ完全にアプリの外部で実行されます これらがどのように機能するか 説明することに興奮していますが 最初に違いがわかるように プロセスがどう機能するかについて話します
進行中のアプリはタッチに応じて becomeFirstResponderを呼び出すなど 最初に入力を要求します これにより すべてのビューを初期化するための 一連の作業が開始されます それが完了すると システムはアニメーションを実行して 入力画面を表示します そのあと アプリは タッチイベントが受信されるまで アイドル状態になるか アプリ側の作業を実行し テキスト挿入が作られます
アウトプロセスでは 少し異なる動作をします アプリが becomeFirstResponderを呼び出すなど 再度入力を要求すると アプリはいくつかの初期計算を実行し そのあとキーボードプロセスが UIを非同期に初期化します この間 アプリはアイドル状態になるか アプリ側の作業を実行します 準備が完了すると入力画面が表示され 2つのプロセス間の アニメーションが調整されます キーボードUIが起動したので キーボードの境界内で発生する タッチイベントを待ちます それらをアプリのテキスト挿入に変換します ほとんどのアプリでは これらの変更は完全に透過的であり ユーザーが選択する必要はありません ただしこの新しい非同期アプローチの側面は 入力全体にあり タイミングに わずかな違いが生じる可能性があります アプリがテキスト入力選択範囲の変更か その他のテキスト操作のタイミングに 特に敏感な場合は この新しい構造を 念頭に置いておく必要があります iOS入力の多様性について説明したところで アプリをデザインする時に考慮すべき 比較的新しいシナリオの いくつかについて話しましょう もちろん最も一般的な使用例 つまりキーボードを備えた全画面アプリは 誰もがよく知っています これはアプリとキーボードの両方が 全画面表示である比較的単純な使用例です キーボードの調整は キーボードの高さの値だけ ビューを上に移動するだけで簡単です しかし ステージマネージャでは システムはそのモデルから離れつつあります 高度なマルチタスクでアプリは必ずしも 全画面で表示されません つまりキーボードが起動する時 アプリのビューを正しく調整するには 特別な注意が必要です それはキーボードとアプリのシーンが 一致しなくなったためです またアプリをコンテキストに合わせて 適切に調整するには いくつかの追加の変換を行う必要があります 例えばこのシナリオでアプリの調整は 実際はキーボードの高さのYではなく Y'として示される キーボードとアプリの交差部分によって 調整する必要があります 画面上に複数のシーンがあるため 計算の調整は1つもない場合があります というのも それぞれ異なる計算と調整が 必要になる可能性があるからです 最近導入されたハードウェアキーボードを 使用したシナリオもいくつかあります ハードウェアキーボードを接続すると システムは画面の中央に アシスタントツールバーを表示します このフルサイズのツールバーが表示されると キーボードの一部として機能し 邪魔にならないように ビューを調整する必要があります フリッジェスチャを使用して このツールバーを最小化することもできます ステージマネージャの外では 既存の動作を維持しています このミニツールバーは キーボードの一部として機能せず ビューと重なって表示されます ユーザーはツールバーを 画面の反対側にドラッグすることで その下のコンテンツにアクセスできます ただし ステージマネージャでは ミニツールバーは キーボードの一部として機能します 使用例に応じて スクロール オフセットを更新したり 入力アクセサリビューを 押し上げることもでき 必要に応じて その他のレイアウト調整を行います ここで説明すべきシナリオやニュアンスが たくさんあることはわかっていますが 嬉しいことに適切なAPIを使用すると システムがほとんどの作業を行ってくれます では キーボードレイアウトガイドについて 話しましょう iOS15で導入された キーボードレイアウトガイドは ご存知かもしれません キーボードに合わせて自動的に調整される 簡単な自動レイアウトガイドを提供し 昨年 さらに機能を追加しました 実際これは現在 「Spotlight」や「メッセージ」など いくつかの複雑なAppleアプリで 使用されています これはビューとガイドの間に 制約を1行追加するだけで 簡単に導入できるため 推奨されるアプローチです では これで何が得られるのかを 正確に説明しましょう 既存のデフォルトの動作は次の通りです キーボードレイアウトガイドは キーボードが画面上に表示され ドッキングしている場合 つまりキーボードが 画面の下部に触れている時です iPad上でキーボードがフローティングされて ドッキングされていない場合など ガイドの高さはビューの下部の セーフエリアと一致します 最後にタッチポイントがガイドと交差すると ガイドはキーボードを閉じる表示 を追跡します iOS17では カスタマイズオプションが拡張され
必要な動作を正確に得るために UIKeyboardLayoutGuideには 3つのプロパティが追加されました まずUndockedKeyboardに従います デフォルトでガイドは フローティングキーボード またはミニツールバーを オフスクリーンキーボードと同様に扱います ただしtrueに設定すると ガイドがアプリのウインドウの 上にある限り フローティング状態でも キーボードに従い続けます 次は BottomSafe領域を使用します デフォルトでは キーボードレイアウトガイドは キーボードが閉じられた時の セーフエリアの高さを追跡します ただし falseに設定すると usesBottomSafeAreaは 代わりにビューの下部を追跡します この場合は画面の下部です これはいつ役立つでしょうか? これでキーボードを閉じた時に 背景を拡張して 画面の下部をカバーできるようになり キーボードが表示された時の調整も行い InputAccessoriesView と同様に動作します 実際これはこのプロパティの 非常に興味深い使用例なので どのように機能するか話しましょう 以下のコードは 下部のセーフエリアの 上にあるテキストフィールドと キーボードが閉じられた時にのみ ビューの下部まで広がる背景を備えた 単純な入力アクセサリのような ビューを取得するコードです この場合垂直方向の制約が興味深いため ここではこの制約のみを扱っています まず useBottomSafeAreaを false に設定しましょう 次に テキスト フィールドの上部を 背景の上部に結び付けます この時2つの間のシステムスペースを使用し テキストフィールドにパディングを加えます 次にガイドの上部を テキストフィールドの下部に固定して 少なくともシステム間隔をあけて テキストフィールドが 常にキーボードの上にあることを確認します ここでは「より大きい」ことが重要です キーボードが画面外にある場合 下部のセーフエリアインセットの上に 留まるように 十分な柔軟性が必要になります また ガイド上部のアンカーを 背景の下部に結び付けましょう これでガイドが画面外にある時 背景が必ず一番下まで表示されます これは usesBottomSafeAreaを false に設定したためです 最後に下部のセーフエリアを テキストフィールドの下部と システムの間隔に制限します ここでもキーボードの起動時に 追従するのに十分な柔軟性を確保するため 大なり小なり制約を使用しています これでビューの下部まで広がる背景を持つ アダプティブ ビューが完成しました ただしキーボード上の テキスト フィールド システムの間を保ち 背景をキーボードの 上部に維持するように調整され 入力アクセサリが表示される場合があります
3番目に keyboardDismissPaddingがあります これによりスクロールの パラメータが調整され表示が解除されます 過去にInput Accessoriesのようなビューを 作成しようとした場合 キーボード レイアウトガイドを使用すると キーボードの閉じる表示が 開始されないことに気づいたかもしれません タッチがキーボードと交差するまで この新しいプロパティを使用して それを修正しましょう
KeyboardDismissPaddingプロパティを 使用すると キーボードの閉じる表示に応答する キーボード上のパディングを指定できます これは比較的簡単です 必要に応じてビューの高さを取得し プロパティを設定します 終わりました これでタッチがビューと交差した時に キーボードの閉じる表示が開始されます アプリの構築に使用されるフレームワークは UIKit だけではありません SwiftUIもあります SwiftUIは一般的なケースを 自動的に処理します SwiftUIではキーボードは セーフエリアの一部として含まれており キーボードが閉じられると 画面の下部にある小さな ホーム アフォーダンスを追跡します キーボードを起動すると システムがアニメーション化して セーフエリアを調整し ビューのサイズを自動的に変更します そのため実際にキーボードコードを 記述する必要はありませんが ビューのサイズ変更や位置変更を 希望通りに行うには レイアウトに何らかの作業が必要な 場合があります SwiftUIには素晴らしいリソースが 多くあります リストに書ききれないほど 多くの機能があるため 詳細は 以下のリンク先のドキュメントを 参照してください ここでキーボードを統合するための 追加の手動方法である キーボード通知について説明します SwiftUI とキーボード レイアウトガイドが 登場する前は キーボードをアプリケーションに統合する 唯一の方法は 一連のキーボード通知 「willShow」「didShow」「willHide」 「didHide」を理解し 通知内のフレームと アニメーションの情報に基づいて レイアウトを手動で調整することでした これらはまだ存在しますが システムが代わりに作業するわけではなく 慎重な取り扱いが必要です ステージマネージャの導入により その処理が100%の確率で機能しなくなる 一般的に使用されるパターンが 増加してることに気づきました このパターンは通常キーボード通知を受信し キーボードの高さからの未加工の値を 直接使用することに重点を置いています
さて 以前キーボードの高さと 画面上のアプリの位置が どう相互作用するか微妙な違いについて 議論した時のことを思い出してください この通知がどのように機能するかについて 説明します 各通知は画面座標に対する キーボードの予想されるフレームを 指定します アプリがフルスクリーンの場合など 画面の座標空間と アプリの座標空間が一致する場合 通知に含まれる未加工の高さの値により ビューが予想どおりに 調整されることになります ただし 画面の座標空間と アプリの座標空間が異なる場合 この高さの値はビューを調整するための 正しい値ではなくなります これによりビューが上に押し上げられすぎて 間違った場所に表示される可能性があります 幸いなことに通知処理に いくつかの変更を加えることで 再びスムーズに動作するようになります iOS 16.1 では キーボード通知に対応するUIScreenが 通知のオブジェクトとして 含まれるようになりました これを使用して キーボードがアプリと同じ画面に 表示されることを確認しましょう それ以外の場合は調整は必要ありません 次にビューを基準とした キーボードの配置を表す四角形を計算します これはキーボードの予期される 終了フレーム通知によって提供される 座標空間およびビューを取得することで 実行できます そしてそれらを使用して keyboardFrameEndを座標空間に変換します この新しい四角形を使用すると ビューとConvertedKeyboardFrameEndの 交差を計算し必要なオフセットが決定します ビューとキーボードが重なっている場合 必要なオフセットはビューとキーボードの 交差点の高さになります これにより制約やレイアウトを 自由に調整できます 新しいアウトプロセス構造により 通知の動作に 若干の変更が生じる可能性があるため 知っておく必要があります それについて少しお話しましょう キーボードプロセスのライフサイクルを 概説したこの図を覚えていますか? ここで「アニメーションの起動」と呼ばれる アニメーションフェーズを拡大しましょう インプロセス構造で アプリがキーボードを要求する時に システムはキーボードUIを同期的に初期化し 通知を送信してアニメーションを実行します ただし 新しいアウトプロセス構造では アプリがキーボードを要求すると システムは キーボードUIを非同期的に初期化し 非同期的に通知を送信し アニメーションを実行します これによりタイミングに 若干の違いが生じるため アプリがbecomeFirstResponderの 呼び出しから 何らかの「コールバック」で 通知のタイミングに依存や メインスレッドで重要な作業を実行中の場合 通知の処理が中断される可能性があり 遅れた場合は アプリに影響を与える 可能性があるため この新しいモデルに留意する必要があります ユーザーがアプリに 簡単に入力できるようにするための ヒントとテクニックをすべて確認しました テキスト入力をさらに高速化する新機能と APIを導入できることを嬉しく思います それがインライン予測です iOS17では英語キーボードで テキストフィールドに インラインで次のいくつかの単語の予測が 表示されるようになりました これらの予測はデバイス上で安全に生成され フォーカスされたテキストフィールドで 提供されるコンテキスト情報のみ使用します これらの予測を採用するのも非常に簡単です ここには UITextInputTraits プロトコルがあり ご覧の通り 新しいinlinePredictionTypeプロパティが 追加され いくつかのオプションが付属しています デフォルトでインライン予測は ほとんどのテキスト入力フィールドで 有効になりますが 検索フィールドやパスワードフィールドなど 予測が適切ではないフィールドでは 自動的に無効になります もちろんプロパティを明示的に 「yes」または「no」に設定することで アプリの動作を カスタマイズすることもできます それでは重要なポイントを いくつかまとめてみましょう 必ず次のことを行ってください 見た目に関係なく キーボードとシームレスに連携するように アプリをデザインします 時間に敏感なコードを作成する時は 新しいプロセス外キーボードモデルを 念頭に置いてください テキスト入力を高速化するAPIの採用で アプリのエクスペリエンスを向上させます キーボードについて お付き合いいただきありがとうございます ♪ ♪
-
-
6:21 - Keyboard layout guide
view.keyboardLayoutGuide.topAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true
-
7:56 - usesBottomSafeArea
// Example of using usesBottomSafeArea to create keyboard and text view aligned with safe area view.keyboardLayoutGuide.usesBottomSafeArea = false textField.topAnchor.constraint(equalToSystemSpacingBelow: backdrop.topAnchor, multiplier: 1.0).isActive = true view.keyboardLayoutGuide.topAnchor.constraint(greaterThanOrEqualToSystemSpacingBelow: textField.bottomAnchor, multiplier: 1.0).isActive = true view.keyboardLayoutGuide.topAnchor.constraint(equalTo: backdrop.bottomAnchor).isActive = true view.safeAreaLayoutGuide.bottomAnchor.constraint(greaterThanOrEqualTo: textField.bottomAnchor).isActive = true
-
9:40 - Keyboard dismiss padding
var dismissPadding = aboveKeyboardView.bounds.size.height view.keyboardLayoutGuide.keyboardDismissPadding = dismissPadding
-
12:11 - Handle willShow or hideKeyboard notifications
func handleWillShowOrHideKeyboardNotification(notification: NSNotification) { // Retrieve the UIScreen object from the notification (Added iOS 16.1) guard let screen = notification.object as? UIScreen else { return } // Determine if the notification’s screen corresponds to your view’s screen guard(screen.isEqual(view.window?.screen)) else { return } // Calculate intersection with keyboard let endFrameKey = UIResponder.keyboardFrameEndUserInfoKey // Get the ending screen position of the keyboard guard let keyboardFrameEnd = userInfo[endFrameKey] as? CGRect else { return } let fromCoordinateSpace: UICoordinateSpace = screen.coordinateSpace let toCoordinateSpace: UICoordinateSpace = view // Convert from the screen coordinate space to your local coordinate space let convertedKeyboardFrameEnd = fromCoordinateSpace.convert(keyboardFrameEnd, to: toCoordinateSpace) // Calculate offset for view adjustment var bottomOffset = view.safeAreaInsets.bottom // Get the intersection between the keyboard's frame and the view's bounds let viewIntersection = view.bounds.intersection(convertedKeyboardFrameEnd) // Check whether the keyboard intersects your view before adjusting your offset. if !viewIntersection.isEmpty { // Set the offset to the height of the intersection bottomOffset = viewIntersection.size.height } // Use the new offset to adjust your UI movingBottomConstraint.constant = bottomOffset // Adjust view layouts and animate using information in notification ... }
-
14:38 - Inline predictions
@MainActor public protocol UITextInputTraits : NSObjectProtocol { // Controls whether inline text prediction is enabled or disabled during typing @available(iOS, introduced: 17.0) optional var inlinePredictionType: UITextInlinePredictionType { get set } } public enum UITextInlinePredictionType : Int, @unchecked Sendable { case `default` = 0 case no = 1 case yes = 2 } let textView = UITextView(frame: frame) textView.inlinePredictionType = .yes
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。