是否可以在详细视图中编辑 SwiftUI 列表元素?

Is it possible to edit a SwiftUI list element in the detail view?

我想在 SwiftUI 的 NavigationView 的详细视图中编辑列表元素的属性。如果我在同一视图中编辑元素的 属性,列表会自动更新。 如果我打开列表元素的详细视图并编辑 属性,它会正确存储在元素中并且也可以在主视图中访问,但列表不会更新。 这是代码的一部分:

@ObservedObject var actions: ActionsList =  ActionsList(l:[Action(dur: 1),Action(dur: 5), Action(dur: 10) ])

NavigationView{
                List(actions.list, id: \.id ){ action in
                NavigationLink(destination: ActionDetail(action:action)){
                    Timer_cell( action: action)
                }
} 
            }

动作细节:

struct ActionDetail: View {
    @State var action: Action

    var body: some View {
        Form {

            HStack {
                Text("Dauer")
                Spacer()
                TextField("Dauer", value: $action.duration, formatter: self.numberFormatter)
            }
        }

    }


    var numberFormatter : Formatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.generatesDecimalNumbers = true
        return formatter
    }()
}

动作列表:

import Foundation

class ActionsList: ObservableObject {
    @Published var list :Array<Action> = [];
    init(l : Array<Action>) {
        list = l;
    }
    init(){
        list = []
    }
}

操作:

struct Action : Identifiable, Equatable, Hashable{
    static func == (lhs: Action, rhs: Action) -> Bool {
        lhs.duration == rhs.duration && lhs.type == rhs.type && lhs.id == rhs.id
    }

    var active: Bool
    var duration: Int       //in seconds
    var type: ActionType
    var id: UUID
    init() {
        active = true
        duration = 10
        type = ActionType.active
        id = UUID()
    }
    init(dur: Int){
        active = true
        duration = dur
        type = ActionType.active
        id = UUID()
    }
    init(_id: UUID, _type: ActionType, dur: Int, _active: Bool){
        id = _id
        type = _type
        duration = dur
        active = _active
    }
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
        hasher.combine(duration)
        hasher.combine(type)
        hasher.combine(active)
    }
}
enum ActionType {
    case pause, active, warmup, cooldown
}

首先,您必须将操作列表更改为环境变量,如下所示

@EnvironmentObject var actions: ActionsList

您可以从下面的代码中调用 ListView

    let contentView = ActionListView().environmentObject(ActionsList(l:[Action(dur: 1),Action(dur: 5), Action(dur: 10) ]))

导航到详细信息视图时

NavigationView{
            List(actions.list.indices){ index in
                NavigationLink(destination: ActionDetail().environmentObject(self.actions.list[index])){
                    Timer_cell( action: self.$actions.list[index]) // this line does the trick
                        }
              }
 }

将您的操作模型 struct 更改为 Class 并遵守 Observable 协议

class Action : Identifiable, Equatable, Hashable, ObservableObject {
    static func == (lhs: Action, rhs: Action) -> Bool {
        lhs.duration == rhs.duration && lhs.type == rhs.type && lhs.id == rhs.id
    }

    var active: Bool
    @Published var duration: Int 
}

希望对您有所帮助。