Можно ли редактировать элемент списка SwiftUI в подробном представлении? - PullRequest
0 голосов
/ 02 апреля 2020

Я хочу редактировать свойства элемента списка в подробном представлении NavigationView в SwiftUI. Если я редактирую свойство элемента в том же виде, список обновляется автоматически. Если я открою подробный вид элемента списка и отредактирую свойство, оно будет правильно храниться в элементе и также будет доступно в главном виде, но список не обновляется. Вот часть кода:

@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)
                }
} 
            }

ActionDetail:

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
    }()
}

ActionList:

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
}

1 Ответ

0 голосов
/ 02 апреля 2020

Сначала вы должны изменить список действий на переменную среды, как показано ниже

@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 
}

Надеюсь, это поможет вам.

...