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

Posted

技术标签:

【中文标题】是否可以在详细视图中编辑 SwiftUI 列表元素?【英文标题】:Is it possible to edit a SwiftUI list element in the detail view? 【发布时间】:2020-04-02 16:32:42 【问题描述】:

我想在 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

【问题讨论】:

您可以分享您正在更新属性的详细信息视图代码吗? 我更新了问题并添加了代码 能否为 ActionsList 模型添加代码? 我也添加了list元素的struct 【参考方案1】:

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

@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
                        
              
 

将您的 Action 模型 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 

希望对你有帮助。

【讨论】:

非常感谢,真的帮了大忙!但我还必须编辑 Timercell

以上是关于是否可以在详细视图中编辑 SwiftUI 列表元素?的主要内容,如果未能解决你的问题,请参考以下文章

尝试更新表单提交 SwiftUI 的先前视图

在 SwiftUI 中更新/编辑数组元素的最佳方法

在 SwiftUI 视图中插入非列表元素

SwiftUI 中的列表视图占据整个屏幕高度

macOS 上的 SwiftUI:带有详细视图和多选的列表

如何防止 TextEditor 在 SwiftUI 中滚动?