我的代码比这复杂一点,所以我创建了一个示例,该示例得到了相同的错误。
当我导航到一个视图时,我要执行一个函数,并将一个变量传递到该视图中。然后,该函数生成一个数组。然后,我想将该数组放入列表中,但出现错误。
如何获取列表以显示生成的数组?
我认为问题在于列表无法更新,因为它已经具有声明的空白数组。
import SwiftUI
struct ContentView : View {
@State var array = [String]()
var body: some View {
List(array.identified(by: \.self)) { item in
Text("\(item)")
}
.onAppear(perform: createArrayItems)
}
func createArrayItems() {
array = ["item1", "item2", "item3", "item4", "item5"]
}
}
答案 0 :(得分:2)
您可以将ObservableObject数据提供程序(例如:ViewModel)与@Published属性一起使用。
struct ListView: View {
@ObservedObject var viewModel = ListViewModel()
var body: some View {
NavigationView {
List(){
ForEach(viewModel.items) { item in
Text(item)
}
}
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ListView()
}
}
#endif
class ListViewModel: ObservableObject {
@Published var items = ["item1", "item2", "item3", "item4", "item5","item6"]
func addItem(){
items.append("item7")
}
}
答案 1 :(得分:0)
愚蠢的UI是一个好的UI
让您的视图保持沉默,尝试以下代码创建动态列表
import UIKit
import SwiftUI
import PlaygroundSupport
struct ContentView : View {
@State var array = [String]()
var body: some View {
List{
ForEach(array.identified(by: \.self)) { item in
Text("\(item)")
}
}
}
}
func createArrayItems()->[String] {
return ["item1", "item2", "item3", "item4", "item5","item6"]
}
PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView(array: createArrayItems()))
答案 2 :(得分:0)
您可以使用Combine框架来更新列表。 每当在DataProvider Object中进行更改时,它将自动更新列表。
struct ContentView : View {
@EnvironmentObject var data: DataProvider
var body: some View {
NavigationView {
NavigationButton(destination: SecondPage()) {
Text("Go to Second Page")
}
List {
ForEach(data.array.identified(by: \.self)) { item in
Text("\(item)")
}
}
}
}
}
在列表中添加项目
struct SecondPage : View {
@State var counter = 1
@EnvironmentObject var tempArray: DataProvider
var body: some View {
VStack {
Button(action: {
self.tempArray.array.append("item\(self.counter)")
self.counter += 1
}) {
Text("Add items")
}
Text("Number of items added \(counter-1)")
}
}
}
它只会通知更改
import Combine
final class DataProvider: BindableObject {
let didChange = PassthroughSubject<DataProvider, Never>()
var array = [String]() {
didSet {
didChange.send(self)
}
}
}
您还需要在SceneDelegate中进行一些更新。此更新可确保ContentView在环境中具有DataProvider对象。
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(DataProvider()))
答案 3 :(得分:0)
@txagPman
我也有您的问题,无法理解如何修改列表。 我能够编写这段代码。 我希望它有用。
import SwiftUI
struct ContentView: View {
@State private var array = createArrayItems()
// @State private var array = [""] - This work
// @State private var array = [] - This not work
@State private var text = ""
var body: some View {
VStack {
TextField("Text", text: $text, onCommit: {
// self.array = createArrayItems() - This work after press return on textfield
self.array.append(self.text)
}).padding()
List (self.array, id: \.self) {item in
Text("\(item)")
}
}
// .onAppear {
// self.array = createArrayItems() - This not work
// }
}
}
func createArrayItems() -> [String] {
return ["item_01","item_02","item_03","item_04" ]
}
答案 4 :(得分:0)
使用这个:
class ObservableArray<T>: ObservableObject {
@Published var array: [T]
init(array: [T] = ) {
self.array = array
}
init(repeating value: T, count: Int) {
array = Array(repeating: value, count: count)
}
}
struct YourView: View {
@ObservedObject var array = ObservableArray<String>()
var body: some View {
}
}