NavigationStack 与 ToolBarItem 按钮操作失败

问题描述 投票:0回答:1

我有一个名为 Handball Coach (NavigationSplitView) 的 iPad 应用程序,其详细信息部分中有一个 NavigationStack。 目前仅 TeamView 可用。

导航是选择一支球队并查看所有球员,或者您可以选择显示所有球员而不选择球队的选项。

当我通过单击 TeamItemView 从 TeamView 打开 PlayerView 时,然后单击玩家以显示 PlayerDetailView。一切正常。

但是当我使用 ToolBarItem 按钮打开 PlayerView 而不选择球队时,PlayerView 就会出现。当我单击播放器时,PlayerDetailView 没有出现。我仍然在 PlayerView 中。 当我单击后退按钮时,我位于 PlayerDetailView 中。当我单击后退按钮时,我就进入了 TeamView。

我希望您能理解我的问题。为什么PlayerDetailView没有出现而我仍然在PlayerView中?

这是我满怀希望的代码,你们中的任何人都看到我的错误或缺乏知识。

提前非常感谢。

这个效果很好。 ContentView -> TeamView -> 选择球队 -> PlayerView -> 选择球员 -> PlayerDetailView

这不起作用或行为错误。 ContentView -> TeamView -> ToolBarItem Button -> PlayerView -> 选择一个玩家 -> PlayerView 移动但停留在 PlayerView 中

struct ContentViewiPad: View {
    
    @State var visibility: NavigationSplitViewVisibility = .all
    @State var selectedSideMenuItem : SideMenuItems? = .team
    
    @State private var navPath = NavigationPath()
    
    let columns = [GridItem(.adaptive(minimum: 360))]
    
    var body: some View {
        
        NavigationSplitView(columnVisibility: $visibility) {
            
            List(SideMenuItems.allCases, id: \.title, selection: $selectedSideMenuItem) { sideMenuItem in
                NavigationLink(value: sideMenuItem) {
                    HStack {
                        sideMenuItem.image
                            .frame(width: 40)
                        Text(sideMenuItem.title)
                    }
                    .padding(.top, 10)
                    .padding(.bottom, 10)
                }
            }
        } detail: {
            NavigationStack(path: $navPath) {
                
                switch selectedSideMenuItem {
                
                case .team:
                    TeamViewiPad()
                    
                case .training:
                    EmptyView()
                    
                case .games:
                    EmptyView()
                    
                case .tools:
                    EmptyView()
                    
                case .settings:
                    EmptyView()
                    
                case .none:
                    EmptyView()
                }
            }
        }
        .navigationSplitViewStyle(.balanced)
        .accentColor(.black)
    }
}
struct TeamViewiPad: View {
    
    @State private var viewState = 0 // 0 = loading data, 1 = loading is done
    
    @State private var teams = [TeamData]()
    
    @State private var showTeamItemActionButton = false
    @State private var showPlayerView = false
    
    @State private var showAlert = false
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    
    let columns = [GridItem(.adaptive(minimum: 280))]
    let columnVSpace: CGFloat = 40 // vertical space between 2 player
    
    var body: some View {
        
        ScrollView {
            
            if (self.viewState == 0) {
                
                VStack() {
                    LoadingView(loadingText: "Daten werden geladen...")
                }
                .padding(.top, UIScreen.screenHeight / 4)
            }
            else {
                LazyVGrid(columns: columns, spacing: columnVSpace) {
                    
                    ForEach(teams, id: \.id) {team in
                        
                        NavigationLink(value: team) {
                            
                            TeamItemViewiPad(team: team, teams: $teams, showTeamItemActionButton: $showTeamItemActionButton)
                        }
                    }
                }
                .padding(.top, 20)
                .padding(.bottom, 20)
            }
        }
        .alert(alertTitle, isPresented: $showAlert, actions: {}, message: { Text(alertMessage) })
        .navigationDestination(for: TeamData.self) { team in
            PlayerViewiPad(team: team)
        }
        .navigationDestination(isPresented: $showPlayerView) { // for ToolbarItem Button
            PlayerViewiPad(team: TeamEmptyData)
        }
        .navigationTitle("Mannschaft")
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button(action: {
                    showPlayerView = true
                }) {
                    Text("Alle Spieler anzeigen")
                    Image(systemName: "person.3.fill")
                }
                .padding(.trailing, 20)
            }
        }
        .onAppear {
            viewState = 0
            Task {
                teams = SQLiteManager.shared.loadTeams()
                viewState = 1
            }
        }
    }
}
struct PlayerViewiPad: View {
    
    let team: TeamData
    
    @State private var players = [PlayerData]()
    
    @State private var showPlayerNewOrEditView = false
    @State private var playerEmptyData = PlayerEmptyData
    
    @State private var showAlert = false
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    
    let columns = [GridItem(.adaptive(minimum: 360))]
    let columnVSpace: CGFloat = 50 // vertical space between 2 player

    var body: some View {
        
        ScrollView {
            
            LazyVGrid(columns: columns, spacing: columnVSpace) {
                
                ForEach(players, id: \.id) {player in
                    
                    NavigationLink(value: player) {
                        
                        PlayerItemViewiPad(player: player)
                    }
                }
            }
            .padding(.top, 20)
            .padding(.bottom, 20)
        }
        .alert(alertTitle, isPresented: $showAlert, actions: {}, message: { Text(alertMessage) })
        .fullScreenCover(isPresented: $showPlayerNewOrEditView, content: {
            PlayerNewOrEditViewiPad(team: team, player: $playerEmptyData, players: $players, playerOrderByType: $playerOrderByType)
                .frame(maxWidth: 720, maxHeight: 720)
                .clipShape(RoundedRectangle(cornerRadius: 10))
                .shadow(color: Color(white: 0.7), radius: 20)
                .presentationBackground {
                    Rectangle()
                        .fill(.ultraThinMaterial)
                        .background(.black.opacity(0.2))
                }
        })
        .navigationDestination(for: PlayerData.self) { player in
            PlayerDetailViewiPad(playerId: player.id, team: team, players: $players, playerOrderByType: $playerOrderByType)
        }
        .navigationTitle(team.teamName != "" ? team.teamName : "Alle Spieler")
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button {
                    showPlayerNewOrEditView = true
                } label: {
                    Image(systemName: "person.crop.circle.badge.plus")
                }
                .padding(.trailing, 20)
            }
        }
        .onAppear {
            Task {
                players = SQLiteManager.shared.loadPlayersOfTeam(team: team, orderBy: playerOrderByType)
            }
        }
    }
}
struct PlayerItemViewiPad: View {
    
    let player: PlayerData
    
    var body: some View {
        
        HStack (alignment: .top) {
            
            ZStack {
                Image(uiImage: player.playerImage.imagePlayerFromBase64)
                    .resizable()
                    .frame(width: 130, height: 130)
                
                Rectangle()
                    .fill(colorDarkGray)
                    .frame(width: 25, height: 25)
                    .offset(x: -52, y: -52)
                
                Text("\(player.playerShirtNumber)")
                    .foregroundColor(.white)
                    .bold()
                    .font(.caption)
                    .offset(x: -52, y: -52)
            }
            .padding(.leading, 20)
            .padding(.trailing, 10)
            
            VStack (alignment: .leading) {
                
                HStack {
                    Text(player.playerName)
                        .font(.system(size: 20, weight: .bold))
                        .foregroundColor(.black)
                        .lineLimit(1)
                    
                    if player.playerNeedsAttention {
                        
                        Image(systemName: "bookmark.fill")
                            .foregroundColor(colorBookmarkRed)
                    }
                    
                    if player.playerHasBirthday {
                        
                        Text("🎉")
                    }
                }
                .padding(.bottom, 10)
                
                HStack (alignment: .center) {
                    
                    Text("Werfen")
                        .font(.system(size: 15))
                    
                    Image(PlayerSkillImage[player.playerSkillThrowBall]!)
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(.trailing, 5)
                    
                    Text("Fangen")
                        .font(.system(size: 15))
                    
                    Image(PlayerSkillImage[player.playerSkillCatchBall]!)
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(.trailing, 6)
                    
                    Text("Passen")
                        .font(.system(size: 15))
                        .padding(.trailing, 2)
                    
                    Image(PlayerSkillImage[player.playerSkillPassBall]!)
                        .resizable()
                        .frame(width: 20, height: 20)
                    
                    Spacer()
                }
                .padding(.bottom, 10)
                
                HStack (alignment: .center) {
                    
                    Text("Prellen")
                        .font(.system(size: 15))
                        .padding(.trailing, 3)
                    
                    Image(PlayerSkillImage[player.playerSkillBounceBall]!)
                        .resizable()
                        .frame(width: 20, height: 20)
                        .padding(.trailing, 4)
                    
                    if player.playerType == 0 { // 0 = Field, 1 = Goalkeeper
                        
                        Text("Spielen")
                            .font(.system(size: 15))
                        
                        Image(PlayerSkillImage[player.playerSkillGame]!)
                            .resizable()
                            .frame(width: 20, height: 20)
                            .padding(.trailing, 4)
                    }
                    else {
                        
                        Text("Torwart")
                            .font(.system(size: 15))
                        
                        Image(PlayerSkillImage[player.playerSkillGoalkeeper]!)
                            .resizable()
                            .frame(width: 20, height: 20)
                            .padding(.trailing, 4)
                    }
                    
                    Text("Athletik")
                        .font(.system(size: 15))
                    
                    Image(PlayerSkillImage[player.playerSkillAthletic]!)
                        .resizable()
                        .frame(width: 20, height: 20)
                    
                    Spacer()
                }
                .padding(.bottom, 10)
                
                HStack (alignment: .center) {
                    
                    Text(player.playerBirthdayTextLine)
                        .font(.system(size: 15))
                        .scaledToFill()
                        .minimumScaleFactor(0.5)
                        .lineLimit(1)
                    
                    Spacer()
                }
            }
        }
    }
}
struct PlayerDetailViewiPad: View {
    
    let playerId : Int
    let team: TeamData // required for refreshing players
    
    @Environment(\.presentationMode) var presentationMode
    
    @Binding var players: [PlayerData] // player from PlayerViewiPad to refresh data after e.g. deletion
    @Binding var playerOrderByType: PlayerOrderByType
    
    @State private var player = PlayerEmptyData
    
    @State private var showPlayerNewOrEditView = false
    @State private var showDeleteConfirmationDialog = false
    
    @State private var selectedDate: Date = Date()
    
    @State private var showAlert = false
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    
    let rowHSpace: CGFloat = 35 // horizontal space
    let rows = [GridItem(.adaptive(minimum: 150))]
    
    var body: some View {
        
        ScrollView {
            
            VStack(alignment: .center) {
                
                HStack(alignment: .top) {
                    
                    Spacer()
                    
                    ZStack {
                        Image(uiImage: player.playerImage.imagePlayerFromBase64)
                            .resizable()
                            .frame(width: 150, height: 150)
                        
                        Rectangle()
                            .fill(colorDarkGray)
                            .frame(width: 30, height: 30)
                            .offset(x: -60, y: -60)
                        
                        Text("\(player.playerShirtNumber)")
                            .foregroundColor(.white)
                            .bold()
                            .font(.system(size: 18, weight: .bold))
                            .offset(x: -60, y: -60)
                    }
                    .padding(.trailing, 20)
                    
                    VStack(alignment: .leading) {
                        
                        HStack (alignment: .center) {
                            Text(player.playerName)
                                .font(.system(size: 35, weight: .bold))
                                .foregroundColor(.black)
                                .lineLimit(1)
                                .padding(.bottom, 20)
                            
                            if player.playerNeedsAttention {
                                
                                Image(systemName: "bookmark.fill")
                                    .font(.system(size: 25))
                                    .foregroundColor(colorBookmarkRed)
                                    .padding(.leading, 10)
                                    .offset(x: 0, y: -8)
                            }
                        }
                        
                        HStack {
                            
                            Image(systemName: "calendar.and.person")
                                .padding(.trailing, 10)
                            
                            Text("Jahrgang " + String(player.playerBirthdayYear))
                                .padding(.trailing, 45)
                            
                            Image(systemName: "figure.handball")
                                .padding(.trailing, 5)
                            
                            Text(player.playerThrowingArm)
                        }
                        .padding(.bottom, 20)
                        
                        if player.playerAddress != "" {
                            
                            HStack {
                                Image(systemName: "mappin.and.ellipse")
                                    .padding(.trailing, 10)
                                
                                Text(player.playerAddress)
                            }
                        }
                    }
                    .padding(.trailing, 100)
                    
                    ZStack {
                        
                        RoundedRectangle(cornerRadius: 5)
                            .fill(.white)
                            .frame(width: 130, height: 150)
                            .shadow(radius: 5)
                        
                        VStack {
                            
                            Text("\(player.playerBirthday.formatDateToString(formatString: "dd"))")
                                .font(.system(size: 50, weight: .bold))
                                .foregroundColor(colorDarkGray)
                            
                            Text("\(player.playerBirthday.formatDateToString(formatString: "MMMM"))")
                                .font(.system(size: 20, weight: .bold))
                                .foregroundColor(colorDarkGray)
                            
                            Divider()
                                .background(.gray)
                                .frame(width: 110)
                                .padding(.vertical, 5)
                            
                            Text("Alter \(player.playerAge) (" + String(player.playerBirthday.formatDateToString(formatString: "EE)")))
                                .font(.system(size: 17))
                                .foregroundColor(colorDarkGray)
                        }
                        
                        if player.playerHasBirthday {
                            
                            Text("🎉")
                                .font(.system(size: 25))
                                .offset(x: 47, y: -57)
                        }
                    }
                    
                    Spacer()
                }
                .padding(.bottom, 50)
                
                HStack(alignment: .top) {
                    
                    LazyHGrid(rows: rows, alignment: .center, spacing: rowHSpace) {
                        
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillThrowBall, skillName: "Werfen")
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillCatchBall, skillName: "Fangen")
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillPassBall, skillName: "Passen")
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillBounceBall, skillName: "Prellen")
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillGame, skillName: "Spielen")
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillGoalkeeper, skillName: "Torwart")
                        PlayerDetailSkillItemViewiPad(skillValue: player.playerSkillAthletic, skillName: "Athletik")
                    }
                }
                
                HStack(alignment: .top) {
                    
                    ZStack {
                        
                        RoundedRectangle(cornerRadius: 5)
                            .fill(.white)
                            .frame(width: 80, height: 80)
                            .shadow(radius: 5)
                        
                        VStack(alignment: .center) {
                            
                            Text(String(player.playerSkillRating))
                                .font(.system(size: 35, weight: .bold))
                                .foregroundColor(colorDarkGreen)
                                .padding(.bottom, 3)
                            
                            Text("Rating")
                                .font(.system(size: 14, weight: .bold))
                        }
                    }
                }
            }
            .padding(.top, 40)
        }
        .alert(self.alertTitle, isPresented: self.$showAlert, actions: {}, message: { Text(self.alertMessage) })
        .fullScreenCover(isPresented: $showPlayerNewOrEditView, content: {
            PlayerNewOrEditViewiPad(team: team, player: $player, players: $players, playerOrderByType: $playerOrderByType)
                .frame(maxWidth: 720, maxHeight: 720)
                .clipShape(RoundedRectangle(cornerRadius: 10))
                .shadow(color: Color(white: 0.7), radius: 20)
                .presentationBackground {
                    Rectangle()
                        .fill(.ultraThinMaterial)
                        .background(.black.opacity(0.2))
                }
        })
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button {
                    showPlayerNewOrEditView = true
                } label: {
                    Image(systemName: "square.and.pencil")
                }
                .padding(.trailing, 20)
            }
            
            ToolbarItem(placement: .topBarTrailing) {
                Button(action: {
                    showDeleteConfirmationDialog = true
                }) {
                    Image(systemName: "trash")
                }
                .confirmationDialog(
                    "Soll \(player.playerName) wirklich gelöscht werden?",
                    isPresented: $showDeleteConfirmationDialog,
                    titleVisibility: .visible
                ) {
                    Button("Ja") {
                        SQLiteManager.shared.deletePlayer(playerId: player.id)
                        players = SQLiteManager.shared.loadPlayersOfTeam(team: team, orderBy: playerOrderByType)
                        presentationMode.wrappedValue.dismiss()
                    }
                    Button("Nein", role: .destructive) { }
                }
                .padding(.trailing, 20)
            }
        }
        .onAppear() {
            player = SQLiteManager.shared.loadPlayer(playerId: playerId)[0]
        }
    }
}

对整个代码感到抱歉,但我相信更容易找出我的错误。

再次非常感谢。 斯文

swiftui-navigationstack
1个回答
0
投票

我必须使用 for: 而不是 isPresented。这就是问题所在。

这是我的解决方案。

Button(action: {
    navPath.append(1)
}) {
    Text("Alle Spieler anzeigen")
     Image(systemName: "person.3.fill")
}

2 导航目的地

.navigationDestination(for: TeamData.self) { team in
    PlayerViewiPad(team: team)
}
.navigationDestination(for: Int.self) { noTeam in
    PlayerViewiPad(team: TeamEmptyData)
}
© www.soinside.com 2019 - 2024. All rights reserved.