Swift - 从不同的视图更新列表
Posted
技术标签:
【中文标题】Swift - 从不同的视图更新列表【英文标题】:Swift - Update List from different View 【发布时间】:2020-12-31 14:51:34 【问题描述】:我的 Swift 项目中有 2 个视图,当我单击第二个视图上的按钮时,我想更新第一个视图中的列表。我不知道该怎么做!如果我在 MainView 中使用静态变量,然后从 secondView 编辑此变量,它可以工作,但不会更新。如果我不使用静态,而是使用@State,它会更新,但我无法从我的 secondView 访问它。
下面是代码:
import SwiftUI
struct ContentView: View
var body: some View
TabView
MainView()
.tabItem()
VStack
Image(systemName: "circle.fill")
Text("MainView")
.tag(0)
UpdateOtherViewFromHere()
.tabItem()
VStack
Image(systemName: "circle.fill")
Text("SecondView")
.tag(1)
struct MainView: View
var arrayList: [CreateListItems] = []
init()
let a = CreateListItems(name: "First Name!")
let b = CreateListItems(name: "Second Name!")
let c = CreateListItems(name: "Third Name!")
arrayList.append(a)
arrayList.append(b)
arrayList.append(c)
var body: some View
return VStack
ZStack
NavigationView
List
ForEach(arrayList) x in
Text("\(x.name)")
.navigationBarTitle("Main View")
struct UpdateOtherViewFromHere: View
func updateList()
//Code that should remove "FirstName" from the List in MainView
var body: some View
return VStack
Button(action:
updateList()
)
Image(systemName: "heart.slash")
.font(.largeTitle)
Text("Click Me!")
struct CreateListItems: Identifiable
var id: UUID = UUID()
var name: String
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【问题讨论】:
你应该将你的 arrayList 移动到一个单独的类中 【参考方案1】:您可以使用@State
和@Binding
分享它
struct ContentView: View
@State var arrayList: [CreateListItems] = []
struct MainView: View
@Binding var arrayList: [CreateListItems]
struct UpdateOtherViewFromHere: View
@Binding var arrayList: [CreateListItems]
或者您使用 MVVM 模式并将列表存储在 ObservableObject
中并使用 @StateObject
/@ObservedObject
(源)并使用 @EnvironmentObject
(连接)在您的视图之间共享它。
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app
class ParentViewModel: ObservableObject
@Published var arrayList: [CreateListItems] = []
init()
addSamples()
func addSamples()
let a = CreateListItems(name: "First Name!")
let b = CreateListItems(name: "Second Name!")
let c = CreateListItems(name: "Third Name!")
arrayList.append(a)
arrayList.append(b)
arrayList.append(c)
func updateList()
let a = CreateListItems(name: "\(arrayList.count + 1) Name!")
arrayList.append(a)
struct ParentView: View
@StateObject var vm: ParentViewModel = ParentViewModel()
var body: some View
TabView
MainView().environmentObject(vm)
.tabItem()
VStack
Image(systemName: "circle.fill")
Text("MainView")
.tag(0)
UpdateOtherViewFromHere().environmentObject(vm)
.tabItem()
VStack
Image(systemName: "circle.fill")
Text("SecondView")
.tag(1)
struct MainView: View
@EnvironmentObject var vm: ParentViewModel
var body: some View
return VStack
ZStack
NavigationView
List
ForEach(vm.arrayList) x in
Text(x.name)
.navigationBarTitle("Main View")
struct UpdateOtherViewFromHere: View
@EnvironmentObject var vm: ParentViewModel
var body: some View
return VStack
Button(action:
vm.updateList()
)
Image(systemName: "heart.slash")
.font(.largeTitle)
Text("Click Me!")
【讨论】:
为什么在“ContentView”中使用@State
?这只是为了测试还是有合理的理由?
因为@State
是事实的来源。它需要在 ParentView 中,以便孩子们可以共享它。它不必在ContentView
中,它只需要在ParentView
中,因此可以与孩子建立双向连接(@Binding
)。
但需要注意的是,从 View
updateList()
操作列表是一种不好的做法,并且您的 MainView
init()
中的代码应该与 ObservableObject
一起位于数组本身。这使得代码可重用和解耦。
我添加了一些代码来说明基础知识。你应该看看 Apple SwiftUI 教程developer.apple.com/tutorials/swiftui以上是关于Swift - 从不同的视图更新列表的主要内容,如果未能解决你的问题,请参考以下文章