Ios 属性更改后在SwiftUI中更新列表

Ios 属性更改后在SwiftUI中更新列表,ios,swift,list,swiftui,Ios,Swift,List,Swiftui,我有一个程序,有两个主要类,团队和玩家。团队有一个内置的数组,其中包含23个Player类的实例,它们都有自己的属性和方法。在我的应用程序的主内容视图中,我显示了这些homeTeam.Player的列表,每行都有一个.contextMenu,可以从单个玩家调用editName() 调用editName()时,它将打开一个警报,允许用户在文本字段中输入新名称,然后保存该名称并更改播放器的name属性 我的问题是,列表不会在主视图上更新,播放器名称保持不变,但是当您再次更改它时,名称在文本字段中,因

我有一个程序,有两个主要类,团队玩家。团队有一个内置的数组,其中包含23个Player类的实例,它们都有自己的属性和方法。在我的应用程序的主内容视图中,我显示了这些homeTeam.Player的列表,每行都有一个.contextMenu,可以从单个玩家调用editName()

调用editName()时,它将打开一个警报,允许用户在文本字段中输入新名称,然后保存该名称并更改播放器的name属性

我的问题是,列表不会在主视图上更新,播放器名称保持不变,但是当您再次更改它时,名称在文本字段中,因此它已经更改,只是没有显示

球员级别:

    class Player{
        var playerName: String = ""
        var id = UUID()

        init(playerName: String){
             self.playerName = playerName
        }

        func editName{
            //Displays alert with text field
            self.playerName = newName
        }
    }
团队课程:

    class Team{
        var teamName: String = ""
        var players: [Player] = [Player("Player 1"),
                                 Player("Player 2"),
                                 Player("Player 3"),
                                 Player("Player 4")] //Continues for 23 Players

        init(teamName: String){
             self.teamName = teamName
        }

    }
快速查看:

    List(homeTeam.players) {player in
        HStack{
            Text("\(player.shirtNumber) - \(player.playerName)")
            Spacer()
            Text("\(player.timerText)")
        }
        .contextMenu{
            Button(action: {player.editName()}) {
                Text("Edit Name")
                Image(systemName: "square.and.pencil")
            }                    
        }
    }
我对SwiftUI还比较陌生,但在UIKit和故事板方面有一些经验,所以如果有任何帮助,我将不胜感激。

这里是可能的方法(未经测试,内联键入)

现在将模型视为

class ViewModel: ObservableObject {
   @Published var homeTeam = Team()
}

and updated view

struct ContentView: View {
   @StateObject var vm = ViewModel()

   var body: some View {
    List(Array(vm.homeTeam.players.enumerated()), id: \.1) { (index, player) in
        HStack{
            Text("\(player.shirtNumber) - \(player.playerName)")
            Spacer()
            Text("\(player.timerText)")
        }
        .contextMenu{
            Button(action: {vm.homeTeam.players[i].editName()}) {
                Text("Edit Name")
                Image(systemName: "square.and.pencil")
            }                    
        }
    }
   }
}
以下是可能的方法(未测试,内联键入)

现在将模型视为

class ViewModel: ObservableObject {
   @Published var homeTeam = Team()
}

and updated view

struct ContentView: View {
   @StateObject var vm = ViewModel()

   var body: some View {
    List(Array(vm.homeTeam.players.enumerated()), id: \.1) { (index, player) in
        HStack{
            Text("\(player.shirtNumber) - \(player.playerName)")
            Spacer()
            Text("\(player.timerText)")
        }
        .contextMenu{
            Button(action: {vm.homeTeam.players[i].editName()}) {
                Text("Edit Name")
                Image(systemName: "square.and.pencil")
            }                    
        }
    }
   }
}
  • 将团队一致性添加到ObservieObject
  • 确保homeTeam标记为@ObservedObject var homeTeam:Team
  • 当需要编辑玩家的名字时,调用一个新的方法 团队,而不是球员,可能命名为changeName(球员:球员,到 newName:String)为您进行更改
  • 确保changeName()调用团队方法 objectWillChange.send()以便视图知道团队已更改 (此方法是ObservedObject协议的一部分)。那是什么 使视图重新绘制
HackingWithSwift(@delawaremathguy)的回答--

  • 将团队一致性添加到ObservieObject
  • 确保homeTeam标记为@ObservedObject var homeTeam:Team
  • 当需要编辑玩家的名字时,调用一个新的方法 团队,而不是球员,可能命名为changeName(球员:球员,到 newName:String)为您进行更改
  • 确保changeName()调用团队方法 objectWillChange.send()以便视图知道团队已更改 (此方法是ObservedObject协议的一部分)。那是什么 使视图重新绘制

HackingWithWift(@DelawareMethGuy)的答案--

将模型设为结构,并将视图模型添加为可观察对象,将模型作为已发布属性。是否将播放器类更改为结构?球队也是吗?那么我要把什么变成一个可观察的对象呢?很抱歉,在这方面不是很有经验,请使您的模型成为结构,并将视图模型添加为可观察对象,将您的模型作为已发布属性。是否将player类更改为结构?球队也是吗?那么我要把什么变成一个可观察的对象呢?很抱歉,我没有太多的经验在一个空的视图上测试它,它正是我想要的工作方式;当我尝试在我的项目中实现它时,我在下面的代码中得到了一个错误“转义闭包捕获突变的“self”参数:
let-enter=UIAlertAction(title:“enter”,style:.default){()in-in-self.playerName=alert.textFields![0].text!}
有什么想法吗?您应该只通过视图模型更新模型,因为模型现在是值类型。你会建议让用户输入一个新名称,而不使用我当前使用的textView和alert吗?在空视图上测试它的工作方式正是我想要的;当我尝试在我的项目中实现它时,我在下面的代码中得到了一个错误“转义闭包捕获突变的“self”参数:
let-enter=UIAlertAction(title:“enter”,style:.default){()in-in-self.playerName=alert.textFields![0].text!}
有什么想法吗?您应该只通过视图模型更新模型,因为现在的模型是值类型。您建议如何让用户输入一个新名称,而不使用我当前使用的textView和alert?