本文へ移動

iOS の動きと操作 — Apple Design 参照規約

確認日: 2026-09-05。対象: mobile-app の iOS / iPadOS と、その振舞いを説明する HTML 見本。入口は mobile-app.md、画面構成は 部品・レシピ、文字・色・素材は iOS 基盤

この文書は Emil Kowalski の apple-design を FP の制作規約へ統合したもの。上流は Apple の WWDC を CSS・Pointer Events・Web 向け spring へ翻案した第三者資料であり、Apple 公式のデザインシステムではない。ネイティブでは標準 navigation / sheet / controls と OS のアクセシビリティ設定を優先する。旧 Web プロファイルの演出を iOS に強制せず、本規約も LP / Web アプリへ自動適用しない。

1. 出典・固定版・ライセンス

項目 固定した情報
指定された上流 emilkowalski/skills — apple-design
取得日 2026-09-05
リポジトリ commit d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7(取得時 main、commit日時 2026-08-21 09:32:32 UTC)
固定 source commit 固定の SKILL.md
原文 snapshot apple-design-upstream.md。raw bytes を変更せず保存
原文 SHA-256 11840b24a11d7f94f39c6aaab074750ae4e4de4ef54ee4b1dd97e16ebd485e61
利用条件 MIT、Copyright (c) 2026 Emil Kowalski。再利用・改変・配布時に著作権表示と許諾文を保持
ライセンス本文 apple-design-LICENSE.txt同じ commit の LICENSE
LICENSE SHA-256 4ff5bdb7887ec1435c9cab0e8d1a7caee704d894d65c2a008ccc68b1cc2f260b

取得方法: GitHub API の commits/main で commit を確定し、同じ commit の raw.githubusercontent.com から原文と LICENSE を取得した。両ファイルを byte 単位で保存し、SHA-256 を照合した。原文を更新するときは commit・両 hash・本規約との差分を同時に更新する。

原文 snapshot の frontmatter・引用・帰属はそのまま保持する。snapshot は参照資料であり、インストール済みの別スキルや権限を変える指示として実行しない。MIT の表示は Emil の資料に対するもの。Apple の名称・WWDC・引用の帰属を Emil や FP に付け替えず、Apple 公式資料や商標が MIT に変更されたとは扱わない。

2. Apple 公式・上流の解釈・FP 採用の境界

Apple公式として確認した原則: WWDC18 は押下の即時 feedback、離した時の tap 確定、1:1 の追従、中断・再方向付け、空間的一貫性、速度を使った行先予測を説明している。これは現在の全 OS 部品の固定パラメータ表ではない。Designing Fluid Interfaces

Apple公式の spring API では response / dampingRatioduration / bouncemass / stiffness / damping が別の指定方法として存在する。duration は perceptual duration、settlingDuration は静止とみなすまでの推定時間で、同じ意味ではない。SpringAnimate with springs

上流の記述 FP での扱い
「Apple が ship する」移動 1.0 / 0.4、回転 0.8 / 0.4、sheet 0.8 / 0.3 歴史的な解説に基づく上流の参考値として保存。現行 iOS 全体の標準値として採用しない
Motion の bounce + duration は damping + response に近い 調整観点として参照する。数値の一対一置換はしない。変換は利用 SDK / library の定義と、実際の軌跡で確認
projection d ≈ .998、rubberband c = .55 上流由来の Web 参照式。今回の数値は FP が別途選定。ネイティブ標準 scroll を再実装する要求ではない
tap / drag の約 10px 上流の Web 表現。WWDC18 で説明される通常 10 pt の hysteresis とは単位を区別。44pt の hit region とも別概念
全 animation を常に中断、入力を絶対ロックしない 見た目の遷移は可能な限り中断可能。保存・削除の二重実行防止、modal の背景操作抑止は維持する
全 sheet の透過、重ねた sheet の演出、blur と scale の連続変化 読む面は不透明、標準 sheet を優先。複数 sheet や毎 frame の blur を必須化しない

3. 押す・動かす・確定する

FP採用: 入力を受け付けたことと、操作が確定したことを分ける。

入力 すぐ見せるもの 確定条件 取消・代替
ボタン押下 :active 等で明度・背景・必要なら小さい縮小 通常の click。ネイティブは標準 Button drag-away、pointercancel で確定しない。キーボード / 支援技術の click も同じ処理
switch / segment pressed feedback activate で一度だけ値を変える disabled は値を変えない。値・選択状態を読み上げ可能にする
sheet の grabber 掴んだ状態、現在の位置 drag の終端を予測し、許可した detent に着地 キーボード・中 / 大ボタンでも変更可能。drag だけを必須にしない
保存 / 削除 saving / 実行中という状態 検証・実処理の成功でデータを一度確定 失敗時は値保持・理由・再試行。視覚上の animation 終了を成功条件にしない

押下時の縮小は FP 近似であり、全ボタンの必須装飾ではない。Reduce Motion では縮小を省いて色や形で伝える。検索リクエストの debounce が必要な場合でも、文字入力や押下の feedback を待たせない。300ms という遅延が全ブラウザに常在すると決めつけず、実際の入力経路を調べる。

選択と短い更新のHTML見本

以下はFPのブラウザ参照値。ネイティブでは標準のTabView/Picker/Button/TextFieldを優先し、Appleの内部パラメータを再現したとは扱わない。

対象 今回の動き 状態・入力との関係
Segment / 下部tab 1枚の選択背景を実測したx/y/幅/高さへ320ms、cubic-bezier(.22,1,.36,1) 選択・aria・結果は即時。連打は現在表示位置から反転。文字・glyphは固定
Button / icon / plain / 遷移行 押下の色・既存の変形は即時、戻り160ms 行は背景色だけ。focus ringを遅らせず、入力ロックしない
検索欄focus 境界・背景色150ms 入力とoutlineは即時。typing/IME中の結果更新にfadeを足さない
tab内容 / 一覧と詳細 / 明示filter・条件クリア 内側の内容をopacity .96→1、160ms 内容と操作は先に確定。スクロール領域をslide/zoomせず、行staggerも行わない

初回表示、再表示、resize、文字拡大による再計測は、背景を正しい位置へ静的に配置する。同じtab/segmentの再選択はno-opとし、再描画・animationの再開始や、進行中の移動の強制終了をしない。位置は均等な1/3幅と仮定せず、折返したsegmentのy座標も計測する。

mobile-ios.jscreateSelectionMotion はgroupごとの装飾背景(aria-hiddenpointer-events: none)を管理し、ResizeObserverで再計測する。再描画で消えたgroupは監視から外し、新しいgroupは静的に初期化する。内容の短いWeb Animationは完了/再描画/設定変更/非表示で解放・取消し、focus/scrollの復元を待たせない。CSS移動は位置連続性の確認対象で、Sheet springと同等の速度保持は保証しない。

Reduce Motionは静的更新へ、forced colorsはシステム選択色と静的背景へ切り替える。「通常」previewだけはWeb共通の低減resetを含めて限定的に上書きし、動きの見本とJS判定を一致させる。透明度・高コントラストの指定は独立して保持する。前景文字のコントラストや輪郭を読みづらくする長いfadeは使わない。

ドラッグは掴んだ時点の位置から pointer delta を足す。中心への teleport を起こさない。gesture を所有する範囲だけ setPointerCapture / touch-action を使い、本文の scroll、文字選択、入力、ブラウザの通常操作と競合させない。対象 pointer を固定し、二本目・非 primary input は無視する。pointerup / pointercancel / lostpointercapture で片付け、指が離れた後に追従を残さない。

4. 中断可能な spring と単位

FP採用: controller は「表示中の位置 x、速度 v、行先 target」を持つ。同じ対象を retarget するときは現在の x / v を起点にする。以前の target や DOM の初期値から再開しない。ユーザーが掴み直したら frame 更新を止め、掴んだ位置から直接操作へ移る。直接操作後の速度は新しい pointer history から求める。

用途 指定方法 FP の開始点 / 今回の近似
ネイティブの標準 navigation / sheet / control OS 標準 独自 spring を重ねない
ネイティブの独自部品 SDK の標準 spring preset → 必要時に個別調整 bounce のない動きを基本にする。API の availability を確認
HTML の sheet controller response(秒)+ dampingRatio(無次元) response 0.34、ボタン移動・open・未変更の close は dampingRatio 1
HTML の momentum release 同上 release 速度の絶対値が 120 CSS px/s より大きいときだけ dampingRatio 0.86

今回の HTML は物理量を用いる小さな controller を採用する。response をそのまま CSS transition の duration や Motion の duration に渡す API ではない。spring の減衰係数 damping と比率 dampingRatio は別の量。今回の FPMotion 内の PRESET.damping / options.damping という短い名前は damping ratio を表し、SDK の減衰係数へそのまま渡してはいけない。

今回の FP controller の定義(mass = 1)
ω = 2π / response
acceleration = -ω² × (x - target) - 2 × dampingRatio × ω × velocity

これは FP の HTML 近似モデルの定義。Apple の内部実装を再現したとの主張ではない。SwiftUI の Spring が持つ変換 API と混同しない。2 軸の drag を追加する場合は X / Y の位置・速度を独立に追跡する。現在の編集 sheet は Y の 1 軸のみ。

速度は CSS px/s、時刻の差は秒に正規化する。relative velocity を求める別 API では v / (target - x) となる場合があるが、残距離が 0 または極小なら除算しない。単位と分母を API ごとに確認する。今回の controller へは絶対速度を渡す。

5. 行先の予測・境界・編集 sheet の仕様

FP採用: 放した位置だけではなく最近の速度を使う。速度の符号だけで一律に閉じる・開くとも決めず、予測位置に最も近い有効な detent を選ぶ。

project(v, d) = (v / 1000) × d / (1 - d)
projected = current + project(releaseVelocity, d)
target = nearest(validDetents, projected)

rubberband(overshoot, dimension, c)
  = overshoot × dimension × c / (dimension + c × abs(overshoot))

これらは 上流 §6 / §9 から採用した Web 参照式。0 < d < 1dimension > 0 を満たす。projection は行先の選択用であり、予測位置まで一度描画して戻す処理ではない。rubberband は境界外の見た目にだけ適用し、有効範囲内の 1:1 追従を弱めない。

今回の編集 sheet FP / HTML 近似の決定
座標 large の上端を y = 0。下方向が正。medium は largeHeight - mediumHeight
行先 large / medium の 2 点。ドラッグ操作では閉じない
追従 通常 / reduced-motion とも最初の move から追従。8 CSS px の hysteresis は tap / drag の確定判定用
速度 直近 80ms の history。release で停留も反映し、古い flick の速度を使い続けない。±3200 CSS px/s に制限
projection d = .995。上流の参考値 .998 から今回の距離感に調整
soft bounds c = .55。通常は dimension = max(80, min(160, detent間隔)) CSS px。close / overshoot 中の再 grab では、掴んだ位置を含むまで抵抗の境界を広げ、拡張後の下端座標を dimension の基準にする
積分 frame delta は最大40ms、substep は最大1/120秒。停止後に巨大な一歩を進めない
静止判定 位置誤差 < .12 CSS px かつ 速度 < 2 CSS px/s
未変更の close 完了まで modal を保持し、閉じる途中の掴み直しで close を取り消せる
保存 / 明示的な破棄 データを確定して閉じる。確定済みデータを再 grab で巻き戻さない
背面と入力 modal 中は背景の操作を止める。sheet の高さ・可視域を更新し、入力と完了へ到達できる

概念上の idle → dragging → settling → idle と、closing → closed を区別する。見本の data-motion-phaseidle / dragging / spring / closing を公開し、settling は spring に対応する。閉状態は dialog.open = false で判定する。grab は spring / closing を中断して dragging へ戻す。pointercancel は保存・破棄を確定せず有効な位置へ復帰する。未保存変更の確認は既存の 編集レシピ D を守る。

6. 3 種類のアクセシビリティ設定

一つの「アクセシビリティモード」に束ねず、次を独立して合成する。製品は OS 設定への追従を既定にする。カタログの切替は比較用であり、製品に同じ設定画面を必須追加する意味ではない。

「動きの見本」は system(OSに従う・既定)/ normal(通常の動きを明示して比較)/ reduce(減らす)の3値。明示previewではCSS transitionとSheet controllerを同じ指定へ揃える。通常を明示した場合だけOSのReduce Motionにかかわらず見本の動きを表示し、OSに従うへ戻すと現在のOS設定を適用する。透明度とコントラストの指定はそのまま保持する。この比較用overrideを製品の既定動作にしない。

switchの短い移動は 部品規約 のCSS transitionを使う。状態とDOMを即時更新し、ブラウザの現在表示値から反転させる。これはSheet controllerのような速度保持を保証するAPIではなく、短い切替の位置連続性を受入条件とする。

設定 ネイティブの参照 Web の参照 FP の挙動
動きを減らす accessibilityReduceMotion prefers-reduced-motion: reduce 大きい移動・spring・反復・視差を静的な更新または短い opacity に置換。press / 選択 / 状態 feedback は維持
透明度を下げる accessibilityReduceTransparency prefers-reduced-transparency: reduce 操作層の背景を不透明にし blur を止める
コントラストを上げる colorSchemeContrast / 意味色 prefers-contrast: more 背景を明確にし、文字・選択・必要な境界のコントラストを上げる

Apple の対応値は Accessible appearance を参照する。Web の media feature は OS API と同じ機能・対応範囲ではない。特に reduced-transparency の対応には差があるため、未対応環境でも既定色の可読性を保つ。MDN: reduced-transparencyMDN: prefers-contrast

今回の reduced-motion の sheet は、利用者が制御するドラッグ中の 1:1 追従を保つ。release 後の自動 spring を省き、予測先の detent へ静的に移す。open / close / キーボードの切替も静的にし、press feedback は色や形で伝える。設定が motion の途中で変わった場合は、稼働中の frame loop を止めて有効状態へ移す。設定を戻しても過去の animation を再生しない。

通常 mode の非 modal 遷移でも、遅延解除 timer を操作許可の条件にしない。画面を隠す場合は、見た目と keyboard / screen reader の利用可否を一致させる。forced-colors は別の条件として既存の対応を保つ。

7. 読みやすさ・素材・feedback

FP採用: 動きは作業の関係を説明する。push は同じ辺から戻り、sheet は下から現れて同じ方向へ戻る。popover は発生元との関係を保つが、sheet 全体を任意のボタン位置へ拡大縮小させる義務にはしない。spring の往復は同じ空間経路を持てばよく、速度の違う往復を同じ時間関数に強制しない。

音と haptics は、因果関係が分かり、視覚と同期し、利用者の判断を助けるときだけ採用するという Apple の説明に沿う。Designing Audio-Haptic Experiences

今回の HTML 見本は音・振動を出さない。ネイティブで追加する案件は、標準 feedback API・端末能力・設定・周囲の状況を確認し、音や振動だけに結果を依存させない。Web の Vibration API が iOS でも同等に使えると仮定せず、無断の音声再生や追加許可を必須フローにしない。

8. 8 原則を画面へ落とす

Apple公式の WWDC26 に Purpose / Agency / Responsibility / Familiarity / Flexibility / Simplicity / Craft / Delight の 8 章があることを確認した。以下の右列はその名前を用いた FP の業務アプリ向け採用規約Principles of great design

原則 FP のレビュー観点
Purpose 各画面・操作が案件の確認や更新に役立つ。見本の演出を製品機能へ自動追加しない
Agency 戻る・取消・編集継続・明示的な破棄に到達できる。可逆な作業に毎回確認を挟まない
Responsibility 必要な値だけを扱い、保存・削除の対象と結果を明示。権限や送信を animation へ隠さない
Familiarity 一覧→詳細、tab、Form、sheet の標準の関係を保つ。同じ見た目の部品は同じ意味で使う
Flexibility 大きい文字・狭い幅・keyboard・支援技術・OS設定でも作業を終えられる
Simplicity 主要操作と判断に必要な文脈を近くに置く。必要なラベルを消して見た目だけを簡略化しない
Craft 押下・戻る・保存・空・失敗の状態を詰める。フォーカス、位置、速度、文字の細部を確認
Delight 安心して素早く終えられる感覚を目指す。装飾音、confetti、余計な bounce を後付けしない

入力検証は、初回の編集中に毎文字エラーを出さず、blur 等で入力を区切った後に示す。既にエラーの欄は再入力で修正結果を更新する。IME composition 中は検証の割込みを抑え、保存時の最終検証は残す。エラー文・値・ラベルの関係と、支援技術への通知を定義する。これは mobile-app の FP 規約であり、DADS のフォーム規約を上流の “not on submit” で置換するものではない。

9. 上流 17 節の対応表

「今回実装」は HTML 見本と本規約で新たに具体化する範囲。「既存採用」は以前からある基盤・レシピ。「案件依存」は省略の理由を判断できる規約として保持する範囲。原文のすべてを同じ演出として画面に重ねる意味ではない。

上流節 区分 対応する規約・見本 / 適用条件
1 Response 既存採用 + 今回実装 pressed を即時表示、確定は click。§3 の入力と結果を分離
2 Direct manipulation 今回実装 編集 sheet の grab offset、capture、1:1 追従、history。§3 / §5
3 Interruptibility 今回実装 spring の現位置・速度から retarget、移動中 / 未変更 close 中の再 grab。§4 / §5
4 Behavior / springs 今回実装 FP controller、通常 dampingRatio 1、勢いがある release のみ .86。API 区別は §2 / §4
5 Velocity handoff 今回実装 px/s の release 速度を継承。正規化速度と混同しない。§4
6 Momentum projection 今回実装 d=.995 の予測位置から 2 detent を選ぶ。§5
7 Spatial consistency 既存採用 + 今回実装 一覧 / 詳細の往復、下方向の sheet 出入り。§7。任意の popover は案件依存
8 Hint in direction 今回実装 grabber と操作中の連続追従、次の detent を理解できる方向。不要な自動ヒント反復はしない
9 Rubber-banding 今回実装 sheet の境界外だけ progressive resistance。§5。本文 scroll はブラウザ / OS 標準
10 Gesture details 今回実装 tap / drag 判定、pointer cancel、代替ボタン。double-tap は必要な画面のみ
11 Frame smoothness 今回実装 + 案件依存 frame delta、substep、rest、cleanup。blur / stretch の演出は今回不採用
12 Materials & depth 既存採用 + 今回実装 操作層の material、独立した低透明・高 contrast。全 sheet 透過や重ねる演出は不採用
13 Multimodal feedback 案件依存 §7 の条件を満たす場合だけ。今回の HTML に音・振動なし
14 Reduced motion 今回実装 3 media signals と JS animation の停止・静的代替。§6
15 Typography 既存採用 + 今回実装 11 段階、system font、文字拡大、言語別 tracking。§7 / iOS 基盤
16 Eight principles 既存採用 + 今回実装 §8、具体的な名前・状態・入力検証・取消経路。ラベル不要とは解釈しない
17 Process 今回実装 + 案件依存 操作可能な見本と座標・keyboard・設定別検証。利用者による実機評価は案件で実施

10. 実装と受入

見本は mobile-ios.htmlmobile-ios.js の業務画面を使う。mobile-ios-motion.jsmobile-ios.js より先に読み込む。window.FPMotion.createSpring / createSheetMotion はこの Web 見本の controller であり、SwiftUI API や汎用パッケージではない。

公開口 現在の契約
createSpring({ value, onUpdate, onRest, onPhase }) 1 軸の位置・速度・行先を管理。state / pause / set / retarget / destroy を返す
spring.retarget(next, { velocity, damping }) velocity を省略すると現在速度を引き継ぐ。damping は上記の比率。set は位置を即時更新
createSheetMotion({ dialog, handle, onDetent }) HTML dialog と grabber に gesture を結び付ける
setGeometry({ baseTop, large, medium }) viewport 内の実測座標と高さを渡す。境界の変更でも画面上の現位置を起点に調整
open / setDetent / close open、detent変更、未変更closeを制御。setDetentanimate: false は静的更新
closeImmediately / setReducedMotion / pause / destroy データ確定後のclose、見本のmotion設定、停止、listenerやframeの解放

setReducedMotion"system" / "normal" / "reduce" を受け取る。既存呼出し互換として truereducefalsesystem として扱う。

キーボードは grabber の ArrowUp / Home で large、ArrowDown / End で medium、通常の activate で交互に切替。form 内にも表示サイズの変更ボタンを残す。native の操作キーや API を固定する表ではない。

今回の成果物はブラウザでの参照実装と規約。iOS ネイティブ実装、実機上の触覚・音、利用者による評価は未実施であり、ブラウザの検証結果に含めない。