見出し画像

iPhone アプリを自分でつくる 19.


今回の内容: オブジェクトとリスト 1.


前回までつくったVisCalcも オブジェクトを扱ってきました。それはボタンだったりTexiFieldだったりViewプロトコルに準拠した部品たちで、それらを並列で機能させていました。
今回から取り組むのはある一つの構造体から複数のオブジェクトを作成して、それらのオブジェクトから必要な情報を抽出していく方法です。
いわゆる「オブジェクト指向」で説明されるオブジェクトを感じていただけるようにしたいと思います。


今後 数回に渡っての進め方ですが、
 VStack とLazyStack と List の違い
 構造体をオブジェクトにする
 セットされたオブジェクトをリストにする
 リストから詳細表示画面に移行する
 データ(オブジェクト)をユーザーが入力する
 データを保存する

このようなイメージで進めていきたいと思いますが、
急に横道にそれることがありますのでご注意ください。」



まず新しいプロジェクトを作成します。

Project 名を ListPractice とします。
iOS17以降のDeployとします。

リスト形式のコードを試してみます。

VStack

VStack を使用した下のコードを記入してCanvas かシミュレーターで表示してみます。

import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView {
            VStack {
                ForEach(1..<1000) { i in
                    HStack {
                        Text("\(i)")
                        Text("Row \(i)")
                    }
                    .onAppear {
                        print(i)
                    }
                }
            }
        }
    }
}

#Preview {
    ContentView()
}

ScrollView の中にVStackで囲んだForEach(1..<1000)をセットしています。
.onAppear { print(i) } は、 HStack { Text(" ~~~" } が表示されたとき(つまりイニシャライズ:初期化、作られたとき)にConsoleに イテレート(ループ)させる数字を表示させています。

注目するところは画面が立ち上がった瞬間にConsoleに全ての数字が表示されることです。Console で1番から999番までが確認できました。
そして画面をスクロールすると非常に滑らかな動きが確認できます。

再確認する場合は、command + k でコンソールの文字を消してから、再度走らせてみてください。


LazyVStack

次はLazyVStack を使用します。
さきほどのVStack をLazyVStack に修正して、Console をクリアしてから再度動かします。

import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(1..<1000) { i in
                    HStack {
                        Text("\(i)")
                        Text("Row \(i)")
                    }
                    .onAppear {
                        print(i)
                    }
                }
            }
        }
    }
}

今回試したところでは、画面には36番までが表示され、Console 画面に表示された最後の番号は72番でした
LazyVStack を使用するとイニシャライズされるのは一部分だけだということがわかります。
今度はスクロールしてみますが、Consoleの表示を一番下まで表示しておいてから画面をスクロールします。
するとスクロールするごとにConsoleに表示される番号が追加されていきます。
つまり画面表示される際にイニシャライズしていくことがわかります。
こんどは素早くスクロールしてみます。
ほとんど違いがわからないかもしれませんが、VStack を使用した画面の滑らかな動きと比べると、若干、追随が遅くなる感覚があります。
再確認する場合は、command + k でコンソールの文字を消してから、再度走らせてみてください。(Canvas: command + option + p)
今回のテストではText を2つ置いただけなので違いはほとんどでないですが、写真などを扱う際はもうすこし違いを感じられます。


List { ForEach

今度はList を使用します。
List はScroll の機能も持っているので ScrollView は消去してから LazyVStack を List に書き直してください。
Console をクリアしてから再度動かします。

struct ContentView: View {
    var body: some View {
        List {
            ForEach(1..<1000) { i in
                HStack {
                    Text("\(i)")
                    Text("Row \(i)")
                }   
                .onAppear {
                    print(i)
                }   
            }   
        }   
    }   
}

List では画面表示は18番までの表示でConsole も18番までの表示となりました。
List もLazily レイジリーな表示、つまり画面に表示する分だけイニシャライズする構造体だとわかります。
スクロールした際もLazyVStack と同じような動きとなります。


List

最後もList を使用しますが、ForEach を使用しない方法です。
一番シンプルにリスト表示を表すことができます。
動きはList { ForEach } を使用した場合と同じです。
違いは下記にまとめます。

 10 struct ContentView: View {
 11     var body: some View {
 12         List(1..<1000) { i in
 13             HStack {
 14                 Text("\(i)")
 15                 Text("Row \(i)")
 16             }   
 17             .onAppear {
 18                 print(i)
 19             }   
 20         }   
 21     }   
 22 }   

リスト形式で表示する場合の各コードのメリット、デメリット

・ScrollView { VStack { ForEach 
        メリット   : 表現の自由度が高い、動きが非常に滑らか
   デメリット:表示内容の合計容量が多ければ多いほど、立ち上がりが
         遅くなる傾向になる

・ScrollView { LazyVStack { ForEach 
        メリット: 表現の自由度が高い、表示内容の容量が多くても立ち上がりや
         動きの滑らかさに変化が出にくい
   デメリット: Lazily に表示されるので大きな写真などを扱う際に
        スクロールのスムーズさに欠けると感じる場合がある 

・List { ForEach
        メリット: システムが基本的な表示形式に整えてくれる
        表示内容の容量が多くても立ち上がりや動きの滑らかさに
        変化が出にくい
        リストの行削除や行移動などが比較的簡単に行える
   デメリット:表現はList構造体の持つ修飾方法に限られる
        Lazily に表示されるので大きな写真などを扱う際には
        スクロールのスムーズさでVStackには劣る

・List { 
        メリット:システムが基本的な表示形式に整えてくれる
       表示内容の容量が多くても立ち上がりや動きの滑らかさに
       変化が出にくい
       iOS16以降ではリストの行削除や行移動などが簡単にできる
   デメリット:表現の自由度はList構造体の持つ修飾方法に限られる
        iOS15以前ではリストだけでの行削除や行移動はできない
        Lazily に表示されるので大きな写真などを扱う際には
        スクロールのスムーズさでVStackには劣る



まとめ

いかがでしたでしょうか?
いろいろなリストを見てきましたがどれが正しいということはなく、どんなコンテンツを扱うのか、容量はどのくらい増えるのかなどを考えて、どれが一番気持ちよく使い続けることができそうかで選択することになります。

次回もオブジェクトとリストについて進めていきます。

次回第20回内容
  次回は  オブジェクトとリスト 2. です。
          よろしくお願いします。





いいなと思ったら応援しよう!

MasaOno
サポートいただければ、さらに活動を広げることができます!