初心者備忘録　NavigationView関連



前回、NavigationViewに初めて触れた。
本腰を入れて作業する時間以外のところで、掘り下げるための先人の知恵を探して回っている。

↓↓↓前回↓↓↓

https://qiita.com/tokkey/items/078c3079aa7874dc970b

## 参考になりそうな記事

#### その1 NavigationViewの基本

https://qiita.com/k-motoyan/items/6b5077d06efccb426344

__内容__
- `NavigationView`のデフォルトの挙動について説明されている
- 画面が2分割されていたのは`UISplitViewController`の機能らしい
- 画面遷移や「戻る」のボタンが自動で配置されるのは`UINavigationController`の機能らしい
- SplitViewがオンのままだと困ることもあるからオフにできるよ！

<details><summary><strong>感想文</strong></summary>

[前回の日記](https://qiita.com/tokkey/items/078c3079aa7874dc970b)の最後でも若干触れているが、もう少しちゃんと読んでみた

![IMG_8348.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2201389/2102aaf3-bcd7-4f69-8516-d61d337c2a43.png)

これ↑についての話が分かりやすい。
この分割されてしまう現象は`UISplitViewController`の機能と酷似していて、
と同じようになるらしい。

[UINavigationControllerのドキュメント](https://developer.apple.com/documentation/uikit/uinavigationcontroller)
ドキュメント内にそれぞれの基本の機能とか載っていてすごく分かりやすかった。
[UISplitViewControllerのドキュメント](https://developer.apple.com/documentation/uikit/uisplitviewcontroller)
こっちもprimary、Secondaryの説明が図でついててよかった。
二つを総合して考えるとやっぱり[先日描いた図](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2201389%2Fa0f11612-43ba-40b0-a69f-6094bc995e80.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=65d5480ca0d0a1ac32aee75ecbb4e1d8)は正しそうなんだが、「親View」「子View」と呼称したものは一応訂正しておこうかな。
![IMG_8352.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2201389/1934a96d-ece2-4f5b-a0cf-49c64c0545c4.png)
あと、これを訂正するなら僕が「プロパティ」と呼称していたものは「Modifier」と呼ぶのが正しそう。
(どこからどこまでがModifierと呼んでいいものなのかは、まだ謎

いや、僕だって最初にちゃんとドキュメント読んでるんだけど、ね？
でも[NavigationViewのドキュメント](https://developer.apple.com/documentation/swiftui/navigationview)だと思って僕が見たのこれだよ？
マジでなんの成果も得られませんでした状態だったからね？！
みなさんのアウトプット超絶感謝…

ところでswiftUI君、`WithAnimation`を初めて使った時にも思ったけど、
AとBとCの機能をまとめたZというさいきょーコマンド！みたいなのが…たくさんありそうな感じするな…？
今後もドキュメント探しが難航しそうだし、先にAとBとCの機能を単独で知ってしまっていた場合には、Zを使わずにゴリ押しで書き進めてしまいそうなので恐ろしい。

</details>

---

#### その2 NavigationViewのサンプル

https://qiita.com/mochizukikotaro/items/b02385021e4ad0bb1cfa

__内容__

- `NavigationView`を使用した簡単なサンプル(タイトル通り！)
- primary中に`List`が使用されている
- `List`内のコンテンツはusersという配列に格納されている
- 簡単な配列のように見えるが`Identifiable`が香ばしい

<details><summary>感想文</summary>

おっ、配列！
項目が増えてきたら考えなきゃなーと思っていたサンプルがここに！
でもなんかただの配列と違う気がする…いや配列は配列なんだが、オブジェクトみがあるというか…
`Identifiable`とかいうやつ、ニオイますねえ…

</details>

---

#### その3 Identifiableに関する記事

https://qiita.com/railgun-0402/items/cba93a53905e5eb59de9

__内容__

- `Identifiable`は`ForEach`や`List`を使うのに必要な構造体
- そもそも`ForEach`や`List`自体はデータの中身を一切見ない
代わりに一意の識別子を要求してるし、一意の識別子があればそれでいい。
- `Identifiable`プロトコルを使用することで、各インスタンスに安定した識別子を持たせてやれる

<details><summary>感想文</summary>

この記事を読んで、「ラーメン屋の食券システムだ！！！！」っていう解釈をしたのは多分僕だけだと思う。

<details><summary>結論、途中まで考えてなんか違うと気づいたから、そっ閉じ。</summary>

僕はラーメン屋に入ってすぐ「ラーメン、大盛りで。唐揚げのついてくるAセットをお願いします。」と言う。
でも店員の若いにーちゃんは「食券おなしゃーす！！！」と返すんだ。
なるほど、食券制ね。僕が悪かった。
僕は入り口の食券機で'大盛りラーメン''Aセット'の食券を買い、さっきのにーちゃんに渡す。
そうすると店員のにーちゃんは「ラーメン、硬さはいかがなさいますか！」と大きな声で訊いてくる…

炒飯を炒める美味しそうな中華鍋の音や、湯切り最中の音、換気扇の音…やかましい店内では、食券が注文内容を一意に定めるツールなのだ。
確かに店員目線だと「ラーメン大盛り」の一言では、僕がチャーシューメンをイメージしているかもしれないし、味玉ラーメンをイメージしているかもしれないし、
とにかく、会計のタイミングになってから「なんかチャーシュー1枚しか入ってなかったんだけど…」とかお客に言われるのは嫌なのだ。
だったら、喧しい厨房から客のオーダーを聞き取るのはやめて、食券機を導入してしまおう。

麺処〜Foreach〜ではそうして、客の注文(データの中身)に耳を傾ける非効率な作業をとりやめて、
Identifiable社の食券機を導入。客が購入した食券のIDを見て…

…あれ。客が提出してくる食券って普通に被ることもあるし、一意ではないな。うん。全然違うわこれ。

思考の過程は残しておいて損はなかろう。
アホを露呈しただけかもしれないけど、そもそも思考の過程を残すことも兼ねて日記をつけ始めたんだ。
いいんだ。アホなりに、足掻くしかない。

</details>


ここまで来て、「構造体」という記述に引っかかってしまった僕。
構造体…？すとらくちゃー？
あ、僕そう言えば`struct`ってよくわからないまま、雑に宣言様式として認識して使ってたわ。
ちゃんと`struct`について知っておいた方が良さそうだな。

</details>


---

#### その4 struct(構造体)に関する記事

https://qiita.com/yuinchirn/items/98b568d595650eca3334

__内容__
>複数の値を１個のオブジェクトで管理できる。
辞書とは違い、同じ構造のオブジェクトを複製することができる。
クラスとは違い、継承はできない。
クラスが参照型であるのに対して構造体は値型
イニシャライズも関数も使える。

ぐぬぬ…僕の理解度だとまだ読み下せない……
読み下せなさすぎてまるっと引用しちゃった…

---

#### その5 chatGPTに訊ねる「struct」とは

__chatGPTに聞いてみたった__
情報の確かさはさておいて、一旦投げてみた。

僕「ところで今更なんですけど、swiftuiにおけるstructってどういう意味ですか」
<details><summary>chatGPTの回答全文</summary>

めちゃくちゃいい質問です！

SwiftUIにおけるstructは、ビュー（画面の構成要素）を定義するための基本的な構造体です。Swiftのstruct自体は、データを保持するための軽量な型なんだけど、SwiftUIでは「画面の部品」を作るためにバリバリ使います。

例えば：

```swift:
struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}
```

このContentViewというのはビュー（画面の一部）を定義していて、structを使って作られてます。SwiftUIはこのstructを元にして、画面の見た目や動きを「宣言的」に構築していくのが特徴です。

<strong>なんでstructなの？</strong>
- 軽い（メモリ的に）
structは値型だからコピーしやすく、SwiftUIの「状態の変化に応じてビューを再描画する」って仕組みにめっちゃ合ってる。
- イミュータブル（変更不可）で安全
再描画されるたびに新しいstructのインスタンスが作られるから、変更の追跡が簡単。副作用が少ない＝バグりにくい。
- Swiftの言語設計とマッチしてる
Swift自体がstruct推しの言語だから、クラスよりstructを使った方が自然で効率が良い。
<hr>
要するに、**SwiftUIのstructは「一時的なUIの設計図」**みたいなもので、状態が変わるたびにその設計図を元にUIが再構築されるってイメージです。

もっと深掘りしたかったり、クラスとの違いも気になる感じ？

chatGPTの回答終わり
<hr>
</details>

丁寧に訊いたのに、だんだん軽い口調になって草。
でもchatGPT君のこの回答で少し閃いたので、もう一つ質問を投げてみる。

僕「あー、いままでstructをletとかvarの仲間くらいに思ってたんだけど、VBAでいうところの解放が必要なオブジェクトを定義するSetと宣言がくっついたやつ、って感じ？分かりにくかったらごめん」

<details><summary>chatGPTの回答全文</summary>

いや、その例えめっちゃおもしろいし分かりやすい！たぶん言いたいこと、かなり伝わってる。

つまり、VBAで言うところの：

```vb:
Dim myObj As SomeObject
Set myObj = New SomeObject
```

↑これって「変数の宣言」と「オブジェクトの生成」が別れてるじゃん？
でもSwiftのstructって、

```swift:
struct User {
    let name: String
}
```

↑みたいに**「型の定義」と「使うときの宣言（letやvar）」が完全に分かれてるし、
それに加えて、structはメモリ管理（解放）も自動**で、軽くコピーされる値型。
<hr>
VBAと比較するとこんな感じ：

<table border="1" cellpadding="8" cellspacing="0">
  <thead>
    <tr>
      <th>VBA</th>
      <th>Swift（SwiftUI）</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code>Dim</code> で型を宣言</td>
      <td><code>struct</code>で型（設計図）を定義</td>
    </tr>
    <tr>
      <td><code>Set</code> でオブジェクトに代入</td>
      <td><code>let</code> や <code>var</code> でインスタンスを生成</td>
    </tr>
    <tr>
      <td><code>New</code>でインスタンスを作成</td>
      <td><code>User(name: "Taro")</code> みたいに直接呼ぶ</td>
    </tr>
    <tr>
      <td>明示的な解放が必要（<code>Set = Nothing</code>）</td>
      <td>解放は不要。自動で処理される</td>
    </tr>
  </tbody>
</table>
<hr>
だから言い換えると、SwiftUIでのstructは

>「VBAのSetで作ってた一時的なUIオブジェクトを、自動的に管理・再生成してくれる便利な箱」

みたいなイメージ、全然アリ。
SwiftUIでは「状態が変わったらView（＝struct）を作り直す」っていう仕組みだから、structがめちゃくちゃ活躍する。
<hr>
てことで、その視点持ってるとSwiftUIの挙動もよりクリアに見えてくると思う！
他にも「これVBA的にはどう？」みたいなのあったら遠慮なく聞いて〜！


chatGPTの回答終わり
<hr>
</details>

なるほど…？そこそこ僕の解釈も合ってたらしい。
まさかそこまで便利な代物だとは思ってなかったけど。

<details><summary>感想文</summary>
便利な代物として作られたのか、別の目的や意図の結果として便利な代物になったのか分からないけど、そのうちこの疑問は鍵になりそう。
でもまだ今はこの謎を解き明かす時ではない…って気がする(第六感)

>SwiftUIでは「状態が変わったらView（＝struct）を作り直す」っていう仕組みだから、structがめちゃくちゃ活躍する。

これも多分頭に入れておく必要がありそう。
どこかのタイミングで理解が進むはず。
</details>




---

次回以降、NavigationViewを使ってみようと思った初心者僕のための記事まとめでした。
chatGPT君の回答については、いずれ答え合わせができるのでほんのり概略として受け止めておく。