Filtered List
This example is inspired by Apple Documentation (Handling User Input)
This sample covered
- How to use Toggle (More details please check SwiftUI – Toggle Switch
- ForEach in SwiftUI
- @EnvironmentObject
- Filter (Logic)
- NavigationLink
- Button
List with @EnvironmentObject
Let’s check ListView code first.
import SwiftUI struct FilterListView: View { @EnvironmentObject private var userData : UserData var body: some View { NavigationView { List { Toggle(isOn: $userData.showFavoritesOnly) { Text("Show Favorite Only") } ForEach(userData.shikuyorolist) { item in if !self.userData.showFavoritesOnly || item.favorite { NavigationLink(destination: ToggleDetailView(item: item).environmentObject(self.userData)) { ItemWithStarRow(item: item) } } } } } .navigationBarTitle(Text("List")) } } struct FilterListView_Previews: PreviewProvider { static var previews: some View { FilterListView().environmentObject(UserData()) } }
As I explained last entry, @EnvironmentObject is managed data between multiple views. We can pass this from other views etc…
Check UserData
UserData.swift
import Foundation final class UserData: ObservableObject { @Published var showFavoritesOnly = false @Published var shikuyorolist : [FavoriteItem] = [ FavoriteItem(id: 1, name: "shikuyoro", imageName: "shikuyoro", time: "2020/06/09 12:00", favorite: true), FavoriteItem(id: 2, name: "shikuyoro", imageName: "shikuyoro", time: "2020/06/11 23:00", favorite: false) ] }
ObservableObject is as it is. In Android, there is similar concept. ObservableObject.
@Published is needed to apply observable.
So, this class is changeable and monitored by views.
Next, check NavigationLink destination
ToggleDetailView.swift
import SwiftUI struct ToggleDetailView: View { @EnvironmentObject var userData: UserData var item : FavoriteItem var index: Int { userData.shikuyorolist.firstIndex(where: { $0.id == item.id })! } var body: some View { VStack { Image(item.imageName) .clipShape(Circle()) .overlay(Circle().stroke(Color.white, lineWidth: 4)) .shadow(radius: 10) .scaledToFit() Spacer() Button(action: { self.userData.shikuyorolist[self.index] .favorite.toggle() }) { if self.userData.shikuyorolist[self.index] .favorite { Image(systemName: "star.fill") .foregroundColor(Color.yellow) } else { Image(systemName: "star") .foregroundColor(Color.gray) } } } } } struct ToggleDetailView_Previews: PreviewProvider { static var previews: some View { let userData = UserData() return ToggleDetailView(item: userData.shikuyorolist[0]) .environmentObject(userData) } }
This View also has @EnvironmentObject passed by parent view.
And this view has button. Press button and change UserData. UserData is observable and change here and update parent view data, too.
Finally, how to use this in SceneDelegate
SceneDelegate.swift
This is not full code. Only important point
let contentView = FilterListView().environmentObject(UserData())



コメント