【Swift】Environment:EditModeとは?Listの編集モードの動的な切り替え

【Swift】Environment:EditModeとは?Listの編集モードの動的な切り替え

この記事からわかること

  • Swift UIList構造体EditMode操作する方法
  • 環境値(Environment)の取得
  • コードから動的切り替えるには?
  • ViewModelモード状態を保持するには?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

EditModeとは

Swift UIのListでは行の入れ替えや削除を有効にしている状態が列挙体EditModeで管理されています。

公式リファレンス:EditMode

enum EditMode {
    case active    // アクティブ
    case inactive  // 非アクティブ
    case transient // 一時アクティブ
}

例えば行の入れ替えを実装するためには以下のようになりますが、EditButtonを使用することでEditModeを意識することなく切り替えることが可能になっています。

struct ContentView: View {

    @State  var langs = ["Swift", "Kotlin", "Objective-C", "Java", "Dart"]

    var body: some View {
        VStack {
            List {
                ForEach(langs, id: \.self) { lang in
                    Text(lang)
                }.onMove { sourceSet, destination in
                    // 配列の中身も移動
                    langs.move(fromOffsets: sourceSet, toOffset: destination)
                }
            }.toolbar { EditButton() }
        }
    }
}

activeになっていると以下のように右側にアイコンが表示され、並び替えやスワイプでの削除が可能になります。

【Swift UI】Listの行の順番を入れ替える方法!onMoveの使い方

※Listで並び替えやスワイプ削除を実装するにはForEachonMoveonDeleteの実装が必要になります。

環境値(Environment)として取得する

Swift UIではEditMode環境値として取得することが可能になっています。そのためEditButtonを使用せずともモードの切り替えを実装することが可能です。

@Environmentプロパティラッパ

おすすめ記事:【Swift UI】@Environmentとは?使い方と使用可能なキー値一覧

Swift UIで使用できるProperty Wrapper(プロパティラッパ)の@EnvironmentからEditModeの値に参照することができます。

@Environment(\.editMode) var editMode

値を参照、変更するにはwrappedValueプロパティを使用します。

実装例

struct ContentView: View {

    @State  var langs = ["Swift", "Kotlin", "Objective-C", "Java", "Dart"]

    @Environment(\.editMode) var editMode
    var body: some View {
        VStack {
            List {
                ForEach(langs, id: \.self) { lang in
                    Text(lang)
                }.onMove { sourceSet, destination in
                    // 配列の中身も移動
                    langs.move(fromOffsets: sourceSet, toOffset: destination)
                }
            }
            Button {
                if editMode?.wrappedValue == .active {
                    editMode?.wrappedValue = .inactive
                } else {
                    editMode?.wrappedValue = .active
                }
            } label: {
                Text("Mode Change")
            }

        }
    }
}

environmentモディファイア

environmentモディファイアを使用することでモードを切り替えることも可能です。この場合はconstantに設定値を渡します。

environmentモディファイアを使用することでViewModelなどのプロパティに@PublishedEditModeの状態を保持させておき、constantに渡せばViewModelの値が更新されるたびにリンクして更新されるようになります。

実装例

struct ContentView: View {
    
    @State  var langs = ["Swift", "Kotlin", "Objective-C", "Java", "Dart"]
    
    @State  var currentMode:EditMode = .inactive
    var body: some View {
        VStack {
            List {
                ForEach(langs, id: \.self) { lang in
                    Text(lang)
                }.onMove { sourceSet, destination in
                    // 配列の中身も移動
                    langs.move(fromOffsets: sourceSet, toOffset: destination)
                }
            }.environment(\.editMode, .constant(currentMode))
            Button {
                if currentMode == .active {
                    currentMode = .inactive
                } else {
                    currentMode = .active
                }
            } label: {
                Text("Mode Change")
            }
        }
    }
}

この方法を実際に使用してモードを管理しているアプリがあるので参考にしてください。

GitHub:Stock

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index