WWDC Quick Look 💓 By SwiftGGTeam
Build for the iPadOS pointer

Build for the iPadOS pointer

元の動画を見る

ハイライト

iPadOS のポインタ システムの設計コンセプトは「間接タッチ」です。ポインタは、従来のデスクトップ システムのマウス ポインタではなく、指の延長です。多くのシステム コンポーネントと一部の標準コントロールには、すでにポインター サポートが組み込まれています。 UIButton などのコントロールは API を通じて有効化およびカスタマイズできますが、カスタム UI は UIPointerInteraction で適合させる必要があります。

主要内容

iPadOS 13.4 では、ユニバーサル ポインティング デバイスのサポートが iPad に追加されます。問題が発生します。iPad のインターフェイスは長い間、指によるタッチを中心に設計されており、多くのコントロールのクリック可能な領域、フィードバック方法、およびドラッグ ジェスチャは、ユーザーが画面に直接タッチすることを前提としています。デスクトップ マウス モデルをそのまま導入すると、ボタン、キャンバス、テキスト領域、ツールバーのカスタマイズが難しくなりがちです。

Apple の推奨事項は、高レベル API から順に作業を進めていくことです。UIBarButtonItemUISegmentedControlUIMenuControllerUIScrollViewUITextViewUIDragInteractionそしてUIContextMenuInteractionシステムレベルのサポートが得られています。最初にこれらの既成の動作を使用し、次に独自のカスタム ビューを処理すると、アプリとシステムの一貫性を保つことができます (03:16)。

開発者が実際に手を動かす必要があるのは、コントロールのように見えるが、そのセマンティクスを UIKit が自動的に理解できないビューを扱う場合です。セッションでは、キルト シミュレーターを使用してデモを行います。右下隅のルーラー ボタンにはより適切なハイライト範囲が必要で、右上隅のスプール ボタンにはリフト効果が必要で、中央の縫製領域には十字線とグリッドにスナップするポインター領域が必要です。

この共有のメインスレッドは非常に明確です。まずシステム コントロールにデフォルトのポインタ フィードバックを取得させてから、UIButton便利な API スピナー、そして最後に使用するUIPointerInteractionUIPointerRegionUIPointerStyleアニメーションを委任してカスタム UI を処理します。

詳細

1. まず、UIButton の組み込みポインター効果を有効にします。

06:04UIButton2 段階のインターフェイスが提供されます。最初のステップは開くことですisPointerInteractionEnabledの場合、システムはボタンの外観、サイズ、内容に基づいてデフォルトの効果を与えます。2番目のステップに向けてpointerStyleProviderシステムが提案する効果や形状を受け取り、その一部を置き換えます。

// Enable the button's built-in pointer interaction.
myButton.isPointerInteractionEnabled = true

// Customize the default interaction effect.
myButton.pointerStyleProvider = { button, proposedEffect, proposedShape -> UIPointerStyle? in
    // In this example, we'll switch to using the .lift effect by creating a new
    // UIPointerEffect with the .lift type using the proposedEffect's preview.
    return UIPointerStyle(effect: .lift(proposedEffect.preview), shape: proposedShape)
}

キーポイント:

  • isPointerInteractionEnabled = trueボタンをシステム ポインター システムに入力させます。
  • pointerStyleProvider一時停止時に呼び出され、ボタンレベルのカスタマイズに適しています。
  • proposedEffectそしてproposedShapeシステムから判断すると、最初にそれらを再利用することで、不要な視覚的なバイアスを減らすことができます。
  • .lift(proposedEffect.preview)デモのスプールボタンなど、独自の形状を持つボタンに適しています。
  • 戻るnilシステムは引き続きデフォルトのスタイルを使用します。戻るUIPointerStyleカスタム スタイルを使用する場合。

2. コンテンツエフェクトを使用してフローティング範囲を調整します

(07:05) ポインターのスタイルは、コンテンツ効果と形状のカスタマイズに分かれています。コンテンツ効果はポインタをビューに変換し、ビューに視覚処理を適用します。Session のルーラー ボタンの問題は、ハイライトされた領域が狭すぎることです。解決策は、ポインターの形状に少しのパディングを追加することです。

// Create a UIPointerStyle that applies the .highlight effect.

// Outset the view's frame so the pointer shape has some generous padding around the view's contents.
// Note that this frame must be in the provided UITargetedPreview's container's coordinate space.
// In the majority of cases (where the preview doesn't have a custom container), this is just the view's superview.
let rect = myView.frame.insetBy(dx: -8.0, dy: -4.0)
let preview = UITargetedPreview(view: myView)

return UIPointerStyle(effect: .highlight(preview), shape: .roundedRect(rect))

キーポイント:

  • myView.frame.insetBy(dx: -8.0, dy: -4.0)負の値を使用して四角形を拡大し、ポインターがボタンに早くスナップするようにします。
  • UITargetedPreview(view:)どのビューがホバー視覚効果に参加するかをシステムに指示します。
  • .highlight(preview)ツールバーとボタンの一般的な強調表示効果に対応します。
  • .roundedRect(rect)ポインターの変形された外側の輪郭を決定します。
  • コメントは、座標空間がプレビューのコンテナーと位置合わせされる必要があることを強調しています。そうでないと、ハイライト位置がオフセットされます。

3. 形状のカスタマイズを使用してコンテキストを表現する

(08:02) 形状のカスタマイズでは、ポインターの形状と移動の制約のみが変更されます。テキスト領域は典型的な例です。ポインタは垂直ビームになり、垂直軸に拘束され、あたかもテキスト行に添付されているかのように移動します。

// Create a UIPointerStyle that changes the pointer into a vertical beam.

let beamLength = myFont.lineHeight
return UIPointerStyle(shape: .verticalBeam(length: beamLength), constrainedAxes: .vertical)

キーポイント:

  • myFont.lineHeight梁の高さを現在のテキスト レイアウトと一致させます。
  • .verticalBeam(length:)表現力豊かなテキストがシーンを挿入または特定します。
  • constrainedAxes: .verticalポインタが指定された軸に沿って拘束されて表示されます。
  • このモードは、キルト シミュレーターの直線ガイダンス モードにも表示されます。ポインタが水平グリッド ラインに吸着して、ユーザーが直線を縫うのを助けます (17:45)。

4. UIPointerInteraction を使用してカスタム領域を管理する

(13:09) カスタム キャンバスには UIButton などのセマンティクスがなく、Session オプションが直接追加されますUIPointerInteraction。デフォルトでは、インタラクションはビュー全体をカバーします。サブエリア内でスタイルを切り替えたい場合は、実装しますUIPointerInteractionDelegateリージョンリクエストとスタイルリクエスト、違いを入れてくださいUIPointerRegion異なるものにマッピングされるUIPointerStyle

この機構により、有効エリアを拡大することもできる。セッションは 19:20 で、「磁力」を強化するためにより大きなポインター領域を提供できるが、その領域はインタラクション ビューのヒット テスト可能な領域内に収まる必要があると述べました。領域がビューを超える場合は、拡張された領域がビューにヒットできるように、同時に hit-test をオーバーライドする必要があります (19:20)。

5. ポインターの入力と終了にアニメーションを追加します。

(21:31) 磨きの最後の層は、ポインター アニメーションと同時に他の UI を調整することです。UIPointerInteractionDelegatewillEnterそしてwillExitAnimator が提供され、開発者は同じアニメーション タイムラインに独自のアニメーションを追加できます。セッション用UISegmentedControl非表示のセパレータの例でこのテクニックを説明します。

func pointerInteraction(_ interaction: UIPointerInteraction,
                        willEnter region: UIPointerRegion,
                        animator: UIPointerInteractionAnimating) {

    // Fade out separator when entering region.
    animator.addAnimations {
        self.separatorView.alpha = 0.0
    }
}

キーポイント:

  • willEnter regionポインターが領域に入るとトリガーされます。
  • animator.addAnimationsカスタム アニメーションはシステム ポインター アニメーションに接続されます。
  • separatorView.alpha = 0.0ホバー状態での視覚的なノイズを減らすために、周囲のクロムに調整が行われます。
func pointerInteraction(_ interaction: UIPointerInteraction,
                        willExit region: UIPointerRegion,
                        animator: UIPointerInteractionAnimating) {

    // Fade separator back in when exiting region.
    animator.addAnimations {
        self.separatorView.alpha = 1.0
    }
}

キーポイント:

  • willExit region入る前にインターフェイスの状態を復元するために使用されます。
  • 同じアニメーターを使用すると、セパレーター効果とポインター効果の間の一貫性のないリズムを回避できます。
  • このタイプのアニメーションは、ホバー状態をきれいにすることを目的として、仕切り、二次クロム、または一時的なプロンプトを非表示にするのに適しています。

重要ポイント

  • カスタム ツールバー ボタンの完成: やるべきこと: 合格したすべてを確認しますcustomViewボタンをバーに入れます。実行する価値がある理由: システムは標準を自動的に処理することしかできません。UIBarButtonItem、カスタム ビューはそれ自体でポインターの動作を宣言する必要があります。開始方法: 最初に開きますisPointerInteractionEnabled、次に使用しますpointerStyleProviderシステムによって提案された効果と形状を再利用します。

  • キャンバス インターフェイスに正確なポインタを追加します: やるべきこと: 描画、編集、植字、地図注釈などの領域で特別なポインタの形状を使用します。価値がある理由: セッションのキルト シミュレータは、十字線と軸方向の制約によりクリックの配置をより明確にします。開始方法: キャンバスに追加UIPointerInteraction、さまざまなリージョンのデリゲートで返されますUIPointerStyle(shape:constrainedAxes:)

  • ポインタ領域を使用してキー コントロールのスナップ範囲を拡大します: 内容: ポインタが近いときに、小さなボタン、狭いハンドル、密集したリスト項目をスナップしやすくします。実行する価値がある理由: セッションは、領域を拡張すると磁気が強化され、正確な移動のコストが削減できると明確に述べました。開始方法: 視覚的な境界よりも広い範囲を返すUIPointerRegionをクリックし、そのエリアがヒットテスト可能な表示範囲内にあることを確認します。

  • ホバー状態をインターフェイス クロムとリンクします: 何をするか: ポインタが特定の領域に入ったときに、仕切りを非表示にする、背景を弱める、または一時的な補助情報を表示します。実行する価値がある理由:willEnterそしてwillExitアニメーターは、これらの変更をシステム ポインター アニメーションと同期させることができます。開始方法: 2 つのデリゲート メソッドを実装し、separatorView.alpha、補助ラベルの透明性または軽量のハイライトが追加されましたanimator.addAnimations

関連セッション

  • iPadOS ポインターのデザイン - iPadOS ポインターの適応精度、変形、ジェスチャー、キーボード修飾子をデザインの観点から説明します。
  • トラックパッドとマウス入力の処理 — ポインターの移動、ポインターのロック、スクロール入力、トラックパッドのジェスチャー、およびマウス ボタンのイベントについて説明します。
  • iPad 用のビルド — 複数列のレイアウト、リスト、ローモーダル ナビゲーションを備えた、より完全な iPad アプリを変換する方法を示します。
  • iPad 向けに設計 — iPad のデザイン パターンから始まり、サイドバー、ドラッグ アンド ドロップ、キーボード、トラックパッド、アダプティブ レイアウトをカバーします。

コメント

GitHub Issues · utterances