気軽にツリー構造が作れるアプリ。議論でテーマをブレイクダウンする際に使用するなどを想定しています。
- 主な特徴
- ツリーのルートノードを複数追加可能 (ホーム画面から追加)
- ノードをタップすると詳細画面でツリー全体を閲覧 (子ノード追加、長押し削除)
- ノードのテキストは直接編集可
- ツリーをピンチ操作で拡大縮小、ドラッグ操作で移動 (ズームビュー)
- 親ノードの下端から子ノードの上端へ向けて自動で線を描画
project/
├ Hooks/
│ └ WidthForText.swift
├ Models/
│ ├ TreeData.swift
│ └ TreeNode.swift
├ Utilities/
│ └ Preferences.swift
└ Viwes/
├ ContentView.swift
├ DetailView.swift
├ TitleInputModal.swift
├ TreeView.swift
└ ZoomableView.swift
-
Hooks/
WidthForText.swift- ノード名のテキスト長を計算し、テキストフィールドの幅を最適化するためのヘルパー関数。
-
Models/
TreeNode.swift- 各ノードのデータモデル。ノード名、子ノード配列、親ノード参照などを保持。
@Publishedプロパティを持つため、UI とバインドして更新を自動反映する。
- 各ノードのデータモデル。ノード名、子ノード配列、親ノード参照などを保持。
TreeData.swift- アプリ全体のルートノード (
rootNodes) を管理するクラス。ユーザーが追加したツリーの最上位ノードを配列で保持する。
- アプリ全体のルートノード (
-
Utilities/
Preferences.swift- SwiftUI の
PreferenceKeyを使って、ノードの描画領域 (CGRect) を一時的に保持するための定義。 NodeFramePreferenceDataとNodeFramePreferenceKeyにより、親ノードの下端 → 子ノードの上端へ線を描画するために用いられる。
- SwiftUI の
-
Viwes/
ContentView.swift- アプリのメイン画面 (ホーム画面)。
- ルートノードの一覧を表示し、新規ノードの追加や削除を行う。
NavigationLinkでDetailViewに遷移。
DetailView.swift- 選択したツリーを全体表示する画面。
ScrollView+ZoomableView+TreeViewの組み合わせで、ツリーを拡大・縮小・ドラッグしながら閲覧可能。- 子ノード削除のアラートなどもこちらで扱う。
TitleInputModal.swift- ホーム画面から新規ルートノードを追加する際のモーダルビュー。
- タイトル入力とキャンセル/完了ボタンを配置。
TreeView.swift- あるノード (
TreeNode) をルートとして再帰的にビューを生成し、子ノードを横並びに表示。 - GeometryReader + PreferenceKey を用いて、親ノード下端~子ノード上端への線を描画する仕組み。
- ノード名の編集や、+ボタン (子ノード追加) の処理も担当。
- あるノード (
ZoomableView.swift- コンテンツをピンチ操作で拡大縮小、ドラッグ操作で移動できるラッパービュー。
MagnificationGestureやDragGestureをSimultaneousGestureで組み合わせている。
-
Xcode で開く
本プロジェクトを Xcode で開きます。 -
ターゲットとシミュレータを選択
Xcode 上部の Scheme から iPhone シミュレータなどを選択。 -
実行
▶︎ ボタンを押してビルド&実行し、シミュレータ上で動作を確認できます。
-
ホーム画面 (ContentView)
- 右上の+ボタンを押す → モーダルが開く → 新規ルートノードの名前を入力 → 「完了」ボタン
- 長押しで削除アラートを表示、確認後に削除できます。
-
詳細画面 (DetailView)
- ホーム画面でノードをタップすると詳細画面へ。
- �ドラッグでツリー全体を移動。
- 個々のノードはタップで直接名前を編集可能。
- ノードを長押し → 削除アラートが出て OK すれば親ノードの子リストから外れ、ノードが消えます。
- ノードの中で「+アイコン」を押すと新しいノードを追加できます。