【Swift】Environment:EditModeとは?Listの編集モードの動的な切り替え
この記事からわかること
- Swift UIのList構造体のEditModeを操作する方法
- 環境値(Environment)の取得
- コードから動的に切り替えるには?
- ViewModelでモード状態を保持するには?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
EditModeとは
Swift UIのListでは行の入れ替えや削除を有効にしている状態が列挙体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
になっていると以下のように右側にアイコンが表示され、並び替えやスワイプでの削除が可能になります。
※Listで並び替えやスワイプ削除を実装するにはForEach
やonMove
、onDelete
の実装が必要になります。
環境値(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などのプロパティに@Published
でEditMode
の状態を保持させておき、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")
}
}
}
}
この方法を実際に使用してモードを管理しているアプリがあるので参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。