ハイライト
Apple のデザインチームは、visionOS の目と手のインタラクションの中核原則を体系的に説明しました。目を主要な照準機構とするには円形要素、60pt の最小ターゲット領域、動的スケーリングが必要です。ジェスチャーは間接ピンチ(膝の上に手を置く)を優先し、直接タッチはコア体験に限定します。Eye Intent により、シンプルな操作が魔法のような精度を得られます。
主要内容
空間入力の5つのモダリティ
visionOS は複数の入力方式をサポートします。
- 目 + 手(最も中核): ボタンを見て、指を軽くつまんで選択。手は膝の上に置ける
- 音声: 検索時にタイピングせず話す
- キーボード + トラックパッド: 生産性シーンでの効率的入力
- ゲームコントローラー: ゲームシーン
- 直接タッチ: 指で仮想 UI に触れる
本 Session は最も中核となる目と手という2つの新入力方式に焦点を当てます。
目動: 主要な照準機構
(02:21)目は空間体験の主要な照準機構です。システムのすべての UI はユーザーが見ている位置に応答します。どれだけ遠くても、要素を楽に照準できます。
視野の快適さ:
(03:06)無限キャンバスがあっても、ユーザーが見えるのは視野内のコンテンツだけです。中央が最も快適で、端は疲れやすいです。メインコンテンツは視野中央に、ツールバーなどの二次操作は端に置きます。
深度管理:
(04:00)人の目は一度に1つの距離にしか焦点を合わせられません。焦点深度の頻繁な切り替えは眼疲労を招きます。インタラクティブコンテンツは同じ深度に保ち、Z 軸の微小変化で階層を表現します。例えばモーダル表示時、メインビューは後退し、モーダルは元の距離に留まります。
ターゲット領域:
(06:06)目動照準の最小ターゲット領域は 60 points です。要素は 60pt 未満でも、間隔で補えます。標準コントロールには適切なサイズが組み込まれています。
形状設計:
(05:18)円形、カプセル形、角丸矩形を使います。尖った形状は避けます。目は中心ではなく端に焦点を合わせます。形状はフラットに保ち、太い枠線は避けます。テキストとアイコンは中央揃えで十分なパディングを取ります。
動的スケーリング:
(07:13)システムウィンドウは動的スケーリングを使います。遠いと大きく、近いと小さくなり、ターゲット領域サイズを一定に保ちます。固定スケールだと遠方の UI が照準しにくくなります。カスタム UI も動的スケーリングを使うべきです。
向き:
(08:14)システムウィンドウは常にユーザーに向きます。カスタムウィンドウも UI を閲覧者に向けたままにすべきです。傾いた UI は読みにくく操作しにくいです。
Hover 効果
(08:51)すべてのインタラクティブ要素に hover 効果が必要です。ユーザーが要素を見たとき、控えめなハイライトフィードバックを表示します。眼球の動きは速いため効果は控えめに。システムコントロールは自動対応、カスタム要素は手動追加が必要です。
プライバシー保護:
(09:40)目動データは極めてセンシティブです。Hover 効果は App プロセス外でレンダリングされ、App はどの要素にフォーカスがあるかだけを知り、目の正確な位置は分かりません。ジェスチャーでインタラクションが発生したときだけフォーカス情報を受け取ります。
Eye Intent
(10:04)要素を長く見ることは関心のサインです。システムはこれを利用して追加情報を表示します。ボタンの tooltip、Tab Bar のラベル展開、検索ボックスの音声検索トリガーなどです。
アクセシビリティ:
(11:04)Dwell Control により、目だけでコンテンツを選択できます。ボタンに一定時間フォーカスすると、ジェスチャーなしで自動選択されます。
ジェスチャー操作
(12:22)目動照準と組み合わせ、指のピンチが主要な確定方式です。システムは複数のジェスチャーをサポートします。
- 軽いピンチ: 選択(タップ相当)
- ピンチ + ドラッグ: スクロール
- 両手ジェスチャー: ズーム、回転
ジェスチャーロジックは Multi-Touch と類似しており、新たに学ぶ必要はありません。
目 + 手の精密操作:
(14:29)画像ズーム時、ズーム原点は目が見ている位置で決まります。見ている場所が拡大され中央に配置されます。Markup ではブラシカーソルが手に追従しますが、キャンバスの別の場所を見てピンチすると、カーソルは注視位置にジャンプします。
直接タッチ
(15:52)手を伸ばして指で仮想 UI に触れます。近距離操作に適しますが疲れやすいです。適したシーン:
- 物体の近距離観察や操作が必要な体験
- 現実世界の筋肉記憶に基づく操作(仮想キーボードなど)
- 身体活動が体験の中核であるシーン
触覚フィードバック欠如の補償:
(16:51)仮想キーボードのキーは台座の上に浮き、指が近づくと hover 状態とハイライトが表示され、接触瞬間に状態が速く変化し空間オーディオが鳴ります。これらの視覚・聴覚フィードバックが欠如した触覚情報を補います。
詳細
カスタムジェスチャー設計原則
(13:17)標準ジェスチャーで足りない場合、カスタムジェスチャーを設計できます。以下の原則に従います。
- 説明・実行が容易で、ユーザーが素早く習得できる
- システムジェスチャーと明確に異なり、競合を避ける
- 疲れずに繰り返せる
- 誤発動率が低い
- 支援技術ユーザーとの互換性を考慮
- 文化横断で誤解を招かない意味
- UI フォールバックを提供
目に優しいレイアウト実践
import SwiftUI
struct EyeFriendlyLayout: View {
var body: some View {
VStack(spacing: 20) {
// 主コンテンツを視野の中央に配置
MainContentView()
.frame(maxWidth: 600)
// 副次的な操作を下部に配置
HStack(spacing: 24) {
SecondaryButton(icon: "gear", action: {})
SecondaryButton(icon: "share", action: {})
}
}
.padding(40)
}
}
struct SecondaryButton: View {
let icon: String
let action: () -> Void
var body: some View {
Button(action: action) {
Image(systemName: icon)
.font(.title2)
.frame(width: 60, height: 60)
}
.buttonStyle(.borderless)
// 円形のほうが狙いやすい
.clipShape(Circle())
}
}
キーポイント:
- メインコンテンツは大きめ、二次操作は 60pt 最小領域を維持
- 要素間隔は十分に(24pt 以上)誤操作を防ぐ
- 円形/角丸形状で目を中心に誘導
- 尖角と太い枠線は避ける
Hover 効果の実装
import SwiftUI
struct HoverButton: View {
let title: String
let action: () -> Void
@State private var isHovered = false
var body: some View {
Button(action: action) {
Text(title)
.padding(.horizontal, 24)
.padding(.vertical, 12)
}
.buttonStyle(.borderedProminent)
.hoverEffect(.lift)
// カスタム hover 効果
.background(
RoundedRectangle(cornerRadius: 12)
.fill(isHovered ? Color.blue.opacity(0.3) : Color.clear)
)
.onHover { hovering in
isHovered = hovering
}
}
}
キーポイント:
.hoverEffect()でシステムレベルの hover フィードバックを得る- カスタム効果は控えめにし、コンテンツ読取を妨げない
- すべてのインタラクティブ要素に hover フィードバックが必要
深度階層設計
import SwiftUI
import RealityKit
struct DepthHierarchyView: View {
var body: some View {
ZStack {
// 背景コンテンツ(やや遠く)
ContentView()
.zOffset(-20)
// 主コンテンツ(標準距離)
MainView()
.zOffset(0)
// Tab Bar(やや近く、階層を表現)
TabBar()
.zOffset(10)
}
}
}
キーポイント:
- インタラクティブコンテンツは同じ深度に保ち、焦点切り替えを減らす
- Z 軸の微小オフセット(10–20pt)で階層を表現し、大きなジャンプは避ける
- モーダルビューはトリガー要素と同じ Z 位置に保つ
直接タッチのフィードバック補償
import SwiftUI
struct DirectTouchButton: View {
let title: String
@State private var isPressed = false
@State private var proximity: CGFloat = 0
var body: some View {
Text(title)
.padding(.horizontal, 32)
.padding(.vertical, 16)
.background(
RoundedRectangle(cornerRadius: 16)
.fill(isPressed ? Color.blue : Color.blue.opacity(0.3 + proximity * 0.4))
)
.scaleEffect(isPressed ? 0.95 : 1.0)
.animation(.easeInOut(duration: 0.1), value: isPressed)
.gesture(
DragGesture(minimumDistance: 0)
.onChanged { _ in
isPressed = true
// 空間オーディオ効果を再生
playSpatialSound()
}
.onEnded { _ in
isPressed = false
}
)
}
func playSpatialSound() {
// Spatial Audio API を使って触覚フィードバック音を再生
}
}
キーポイント:
- 接近時に hover 状態(明度グラデーション)を表示
- 接触瞬間に素早く応答(0.1 秒以内)
- 空間オーディオでフィードバックを強化
- スケール効果で視覚的確認を提供
重要ポイント
-
既存 App のインタラクションフローを再設計する
- やること: 既存 iOS App のタップ操作を目動照準 + ジェスチャー確定に変更
- 価値: visionOS の目動照準は指タップより精密で、遠距離操作が快適
- 始め方: ボタンを円形/角丸にし、60pt ターゲット領域を確保、
.hoverEffect()を追加
-
Eye Intent で情報表示を最適化する
- やること: ユーザーが要素を長く見たとき、関連詳細を自動表示
- 価値: UI の clutter を減らし、必要なときだけ情報を出す
- 始め方:
onHoverとタイマーを組み合わせ、1 秒注視後に tooltip や詳細パネルを展開
-
ジェスチャー優先の 3D コンテンツ操作を設計する
- やること: 3D モデルビューアに両手ズーム/回転を追加し、目で操作中心を決定
- 価値: 目で操作原点を決める方が自然。両手ジェスチャーは直感的
- 始め方: RealityKit のジェスチャー認識を使い、ズーム原点を目が見ているモデル表面点に設定
-
仮想キーボードの直接タッチフィードバックを最適化する
- やること: カスタム入力 UI で接近検知、接触応答、空間オーディオを実装
- 価値: 触覚のない直接タッチには多層の感覚補償が必要
- 始め方: 浮遊ボタン設計 + 接近ハイライト + 接触スケール + 空間オーディオの組み合わせ
-
Dwell Control サポートを追加する
- やること: すべてのインタラクティブ要素が目だけで選択可能か確認(ジェスチャー不要)
- 価値: 運動障害ユーザーは Dwell Control に依存。アクセシビリティ要件
- 始め方: 標準 SwiftUI コントロールは自動対応。カスタムコントロールは明確なフォーカス状態を確保
関連セッション
- Principles of spatial design — 空間計算プラットフォームの設計原則
- Design for spatial user interfaces — 空間 UI の設計実践
- Create accessible spatial experiences — 空間計算プラットフォームのアクセシビリティ設計
コメント
GitHub Issues · utterances