首页 > 解决方案 > 如何重用视图并为每个视图拥有单独的唯一对象实例

问题描述

我正在为棋盘游戏创建记分牌。棋盘有 4 名玩家。Players 是一个跟踪玩家姓名和得分的对象。我创建了一个 PlayerView。然后我有一个 TwoPLayerView,它将两个播放器设置为一个 HStack,最后我的 Content View 文件使用 TwoPlayersView 作为 VStack。最后我有一个大致类似于这样的观点: 游戏板

我在 PlayerView 中使用我的播放器对象(使用组合框架)。我认为屏幕中的每个 PlayerView 都会有自己的 Player 实例,但我不断得到一个结果,显示只有 Player1(左上角的玩家)受到影响。我尝试创建一个 Game 对象,它是一个环境变量,允许我跟踪游戏中当前处于活动状态(选择)的玩家,但是当我再次点击 Player2(右上角)时,我得到了对 Player1 的响应。我是否设计了错误的程序或者我遗漏了什么?

这是我的 PlayerView 代码:

struct PlayerView: View {
    @ObservedObject var player: Player
    @EnvironmentObject var theGame:Game;
    @State var changeName: Bool = false
   
  //  var playerName:String
    //var score:Int
    var borderSize: CGFloat = 2
    var body: some View {
        ZStack{
            VStack{

                Text(player.playerName)
                    .foregroundColor(.white)
                    .padding(.top, 7)
                    .onTapGesture {
                        changeName = true
                    }
                
                Text("\(player.score.last?.roundAsString() ?? "Round: ")")
                    .padding(.top,7)
                    .foregroundColor(.white)
                    
                
                ExtraDivider(color: .black, width: borderSize)
                        
                    Spacer()
                
                Text("Score")
                    .foregroundColor(.white)
                Text("\(player.score.last?.scoreAsString() ?? "0")")
                    .foregroundColor(.white)
                    .padding(.bottom, 10)
                    
            }
            if changeName{
                VStack{
                    Text("Enter Player/Team Name")
                        
                    TextField("Enter Name Here", text: $player.playerName)
                        .frame(width: 100, height: 25)
                        .background(Color.white)
                        .cornerRadius(5)
                    
                    Text("DONE")
                        .frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: 50, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
                        .cornerRadius(5.0)
                        .onTapGesture {
                            changeName.toggle()
                        }
                    
                }
                .frame(minWidth: 100, idealWidth: 150, maxWidth: 300, minHeight: 100, idealHeight: 100, maxHeight: 200, alignment: .center)
                .background(Color.gray)
                .border(Color.gray, width: 5)
                .cornerRadius(15)
                
                
            }
        }
        .frame(minWidth: 100, idealWidth: 150, maxWidth: 300, minHeight: 100, idealHeight: 100, maxHeight: 200, alignment: .center)
        .background(Color.blue)
        .cornerRadius(10, corners: [.topLeft, .topRight])
        .cornerRadius(30,corners:[.bottomLeft, .bottomRight])
        .aspectRatio(contentMode: .fit)
        .onTapGesture {
            theGame.activePlayer = player.playerName
        }
        
    }
}

我的 TwoPlayerView

struct TwoPlayersInRowView: View {
    @ObservedObject var player1:Player
    @ObservedObject var player2:Player
    
    var body: some View {
        HStack(spacing: 120){
            PlayerView(player: player1)
                .padding(.leading, 20)
                .padding(.bottom, 7)
                .padding(.top,5)
            Spacer()
            PlayerView(player: player2)
                .padding(.trailing, 20)
                .padding(.bottom, 7)
                .padding(.top,5)
            
        }
    }
}

内容视图

struct ContentView: View {
    @EnvironmentObject var theGame:Game
    @State var isPlayer1Active: Bool = false
    @State var isPlayer2Active: Bool = false
    var body: some View {
    
        VStack {
            AdBannerView()
            Spacer()
    
            ZStack{
                addPointsCombinedView()
                    .scaledToFit()
                VStack {
                    TwoPlayersInRowView(player1: theGame.player1, player2: theGame.player2)
              
                    TwoPlayersInRowView(player1: theGame.player3, player2: theGame.player4)
                        .padding(.top, 10)
                }
            
            }
            Spacer()
        }
    }
}

标签: swiftuicombine

解决方案


推荐阅读