# 画面設計書 86-LoadingAnimation画面

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるLoadingAnimation画面の設計仕様を定義するものである。この画面は、長時間実行されるデータ移行処理中にアニメーション付きのローディング表示を行うコンポーネントである。

### 本画面の処理概要

LoadingAnimation画面は、データ移行やその他の長時間実行される処理中に表示されるフルスクリーンのローディング画面である。回転するサテライト画像のアニメーションとステータスメッセージを表示し、ユーザーに処理が進行中であることを視覚的に伝える。キャンセルボタンにより処理の中断も可能。

**業務上の目的・背景**：アプリのアップデートや内部データ構造の変更に伴い、既存データの移行処理が必要になる場合がある。このような処理は時間がかかることがあり、ユーザーにアプリがフリーズしているような印象を与えないよう、視覚的なフィードバックを提供する必要がある。本画面は、処理が進行中であることを明示し、必要に応じてキャンセルするオプションを提供することで、ユーザー体験を改善する。

**画面へのアクセス方法**：アプリ起動時のデータ移行処理や、その他の長時間処理開始時にモーダルで表示される。通常のユーザー操作からはアクセスしない。

**主要な操作・処理内容**：
1. 回転アニメーションの表示開始と停止
2. ステータスメッセージの表示
3. キャンセルボタンによる処理中断
4. アプリがバックグラウンドから復帰した際のアニメーション再開

**画面遷移**：
- 遷移元：アプリ起動処理、データ移行処理開始時
- 遷移先：なし（処理完了または中断で自動的に非表示）

**権限による表示制御**：特になし。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | データ移行 | 主機能 | 長時間処理中のローディング表示 |

## 画面種別

モーダル（フルスクリーン）

## URL/ルーティング

iOSネイティブアプリのため、URLルーティングなし。処理開始時にモーダル表示され、完了時に自動的にdismissされる。

## 入出力項目

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|------|---------|------|------|
| theme | Theme | 入力 | 必須 | 現在のテーマ設定 |
| cancelBlock | (() -> Void)? | 入力 | 任意 | キャンセル時に実行されるクロージャ |

## 表示項目

| 項目名 | 説明 | 表示形式 |
|--------|------|----------|
| サテライト画像 | 回転アニメーションする衛星画像 | 画像（回転） |
| 背景画像 | 背景装飾画像 | 画像 |
| ステータスラベル | 「Updating...」 | テキスト（太字ヘッドライン） |
| キャンセルボタン | 「Cancel」 | ボタン（セミボールドタイトル） |

## イベント仕様

### 1-画面表示開始

viewDidAppear時にアニメーションを開始する処理。

1. `viewDidAppear(_:)`が呼び出される
2. `satelliteImageView.startRotating()`で回転アニメーション開始
3. `UIAccessibility.post`でスクリーン変更通知（statusLabelにフォーカス）
4. `UIApplication.didBecomeActiveNotification`の監視を登録

### 2-アプリアクティブ復帰

アプリがバックグラウンドから復帰した際の処理。

1. `applicationDidBecomeActive(_:)`が呼び出される
2. `satelliteImageView.startRotating()`でアニメーション再開

### 3-画面非表示

viewDidDisappear時にアニメーションを停止する処理。

1. `viewDidDisappear(_:)`が呼び出される
2. `satelliteImageView.stopRotating()`でアニメーション停止
3. `UIAccessibility.post`でスクリーン変更通知（nil）
4. `didBecomeActiveNotification`の監視を解除

### 4-キャンセルボタンタップ

キャンセルボタンを押した際の処理。

1. `tappedCancel(_:)`が呼び出される
2. `cancelBlock?()`でキャンセルクロージャを実行

### 5-フォントサイズ変更

Dynamic Typeに対応したフォント更新処理。

1. `traitCollectionDidChange(_:)`が呼び出される
2. `updateFonts()`が実行される
3. cancelButton.titleLabel?.fontをWMFFont.for(.semiboldTitle3)で設定
4. statusLabel.fontをWMFFont.for(.boldHeadline)で設定

## データベース更新仕様

本画面では直接的なデータベース操作は行わない。表示対象となるデータ移行処理は別コンポーネントで管理される。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| data-migration-status | 情報 | Updating... | 常時表示（ステータスラベル） |
| cancel | アクション | Cancel | キャンセルボタン（CommonStrings） |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| cancelBlockがnil | キャンセルボタンタップ時に何も起きない |
| アニメーション重複開始 | layer.animation(forKey:)で既存チェック、あれば追加しない |

## 備考

- UIViewのextensionでstartRotating/stopRotatingメソッドを定義
- CABasicAnimationでtransform.rotationをアニメーション（1秒で1回転、無限リピート）
- accessibilityViewIsModalがtrueに設定され、モーダル表示時は他要素にアクセス不可
- Themeableプロトコルに準拠し、テーマ変更に対応

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: 基本構造を理解する

ViewControllerの構成とIBOutletを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | プロパティ、IBOutlet、IBAction |

**読解のコツ**: @IBOutletとprivateの組み合わせ、cancelBlockはクロージャプロパティ。

#### Step 2: ライフサイクルを理解する

ViewControllerのライフサイクルとアニメーション制御を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | viewDidLoad、viewDidAppear、viewDidDisappear |

**主要処理フロー**:
1. **14-24行目**: `viewDidLoad()` - テーマ適用、ボタン/ラベル設定、アクセシビリティ設定
2. **30-36行目**: `viewDidAppear(_:)` - アニメーション開始、通知登録
3. **38-44行目**: `viewDidDisappear(_:)` - アニメーション停止、通知解除

#### Step 3: アニメーション実装を理解する

UIView extensionの回転アニメーション実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | private extension UIView |

**主要処理フロー**:
- **61-65行目**: `rotationKey` - アニメーションキー
- **67-78行目**: `startRotating(duration:)` - CABasicAnimation生成と追加
- **79-85行目**: `stopRotating()` - アニメーション削除

#### Step 4: テーマ対応を理解する

Themeableプロトコルの実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | Themeable extension |

**主要処理フロー**:
- **88-100行目**: `apply(theme:)` - 各UI要素のテーマカラー適用

### プログラム呼び出し階層図

```
LoadingAnimationViewController
    │
    ├─ viewDidLoad()
    │      ├─ apply(theme:)
    │      ├─ cancelButton.setTitle()
    │      ├─ statusLabel.text設定
    │      ├─ accessibilityViewIsModal = true
    │      └─ updateFonts()
    │
    ├─ viewDidAppear(_:)
    │      ├─ satelliteImageView.startRotating()
    │      ├─ UIAccessibility.post(screenChanged)
    │      └─ NotificationCenter.addObserver(didBecomeActive)
    │
    ├─ applicationDidBecomeActive(_:)
    │      └─ satelliteImageView.startRotating()
    │
    ├─ viewDidDisappear(_:)
    │      ├─ satelliteImageView.stopRotating()
    │      ├─ UIAccessibility.post(screenChanged, nil)
    │      └─ NotificationCenter.removeObserver()
    │
    ├─ tappedCancel(_:)
    │      └─ cancelBlock?()
    │
    └─ UIView extension
           ├─ startRotating(duration:)
           │      └─ CABasicAnimation(keyPath: "transform.rotation")
           └─ stopRotating()
                  └─ layer.removeAnimation(forKey:)
```

### データフロー図

```
[トリガー]              [画面]                    [アクション]

データ移行開始 ────▶ LoadingAnimation ────▶ 回転アニメーション表示
                    (モーダル表示)
                         │
                         ├─ ユーザー待機
                         │
                         ├─ アプリバックグラウンド→フォアグラウンド
                         │      └─ アニメーション再開
                         │
                         ├─ キャンセルボタンタップ
                         │      └─ cancelBlock実行 → 処理中断
                         │
                         └─ 処理完了通知
                                └─ dismiss
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LoadingAnimationViewController.swift | `Wikipedia/Code/LoadingAnimationViewController.swift` | ソース | メインViewController |
| LoadingAnimationViewController.xib | `Wikipedia/Code/` | XIB | UIレイアウト（推定） |
| WMFFont | `WMFComponents` | ソース | Dynamic Type対応フォント |
| CommonStrings | `Wikipedia/Code/` | ソース | ローカライズ文字列 |
