英文:
SwiftUI nested list calls navigationLink prior to selection
问题
我在Swift UI中遇到了一个嵌套列表的问题,似乎每个列表项都会调用其相应的navigationLink,而不管是否被选中并忽略其被禁用的事实,我不确定为什么会发生这种情况。以下是我的代码,大部分的Swift格式已被删除:
struct Team: Identifiable {
let id = UUID()
let name: String
let icon: String
let teamCode: String
let showTeam: Bool
var items: [Team]?
}
struct NFLView: View {
var userPlayEstimates: UserPlayData
var userAllRosters: userAllRosters
let items: [Team] = [.AFCNorth, .AFCSouth, .AFCEast, .AFCWest]
var body: some View {
VStack {
NavigationStack {
Image("NFL_Logo")
.resizable()
List(items, children: \.items) { row in
NavigationLink {
NFLTeamRosterView(teamName: row.name, teamCode: row.teamCode, userAllRosters: userAllRosters)
} label: {
Text(row.name)
}
.disabled(!row.showTeam)
}
}
}
}
}
extension Team {
static let rai = Team(name: "Raiders", icon: "RAI_Logo", teamCode: "rai", showTeam: true)
static let rav = Team(name: "Ravens", icon: "BAL_Logo", teamCode: "rav", showTeam: true)
static let mia = Team(name: "Dolphins", icon: "MIA_Logo", teamCode: "mia", showTeam: true)
static let buf = Team(name: "Bills", icon: "BUF_Logo", teamCode: "buf", showTeam: true)
static let nwe = Team(name: "Patriots", icon: "NWE_Logo", teamCode: "nwe", showTeam: true)
static let nyj = Team(name: "Jets", icon: "NYJ_Logo", teamCode: "nyj", showTeam: true)
static let cin = Team(name: "Bengals", icon: "CIN_Logo", teamCode: "cin", showTeam: true)
static let pit = Team(name: "Steelers", icon: "PIT_Logo", teamCode: "pit", showTeam: true)
static let cle = Team(name: "Browns", icon: "CLE_Logo", teamCode: "cle", showTeam: true)
static let jax = Team(name: "Jaguars", icon: "JAX_Logo", teamCode: "jax", showTeam: true)
static let oti = Team(name: "Titans", icon: "OTI_Logo", teamCode: "oti", showTeam: true)
static let clt = Team(name: "Colts", icon: "CLT_Logo", teamCode: "clt", showTeam: true)
static let htx = Team(name: "Texans", icon: "HTX_Logo", teamCode: "htx", showTeam: true)
static let kan = Team(name: "Chiefs", icon: "KAN_Logo", teamCode: "kan", showTeam: true)
static let sdg = Team(name: "Chargers", icon: "SDG_Logo", teamCode: "sdg", showTeam: true)
static let den = Team(name: "Broncos", icon: "DEN_Logo", teamCode: "den", showTeam: true)
static let AFCWest = Team(name: "AFC West", icon: "NFL_Logo", teamCode: "AFCW", showTeam: false, items: [Team.rai, Team.kan, Team.sdg, Team.den])
static let AFCNorth = Team(name: "AFC North", icon: "NFL_Logo", teamCode: "AFCN", showTeam: false, items: [Team.rav, Team.pit, Team.cle, Team.cin])
static let AFCSouth = Team(name: "AFC South", icon: "NFL_Logo", teamCode: "AFCS", showTeam: false, items: [Team.jax, Team.oti, Team.htx, Team.clt])
static let AFCEast = Team(name: "AFC East", icon: "NFL_Logo", teamCode: "AFCE", showTeam: false, items: [Team.nwe, Team.mia, Team.nyj, Team.buf])
}
背景信息是,NFLTeamRosterView被设计为接受任何球队,而不是AFC分区的输入,因此被禁用为可选择的列表项。然而,每当我调用这个视图时(特别是我用NFLView(userPlayEstimates: userPlays, userAllRosters: userRosters)
显示一个sheet时),我立即从NFLTeamRosterView中得到一个错误-它被调用在我的第一个列表项上-NFLTeamRosterView(teamName: "AFC North", teamCode: "AFCN")
显然,这是一个问题,因为它会导致我必须设计解决这个问题,但这是否意味着每次我创建这个嵌套列表时,每个navigationLink都会被运行?如果是这样的话,这似乎是一个相当大的计算负担,有没有办法防止这种情况发生?
英文:
I am running into an issue with a nested list in Swift UI where it seems that every list item is making a call to its respective navigationLink regardless of being selected and ignoring the fact that it's disabled, and I'm not sure about why this happens. My code is below, with most of the swift formatting removed-
struct Team: Identifiable {
let id = UUID()
let name: String
let icon: String
let teamCode: String
let showTeam: Bool
var items: [Team]?
}
struct NFLView: View {
var userPlayEstimates : UserPlayData
var userAllRosters : userAllRosters
let items: [Team] = [.AFCNorth, .AFCSouth, .AFCEast,.AFCWest]
var body: some View {
VStack{
NavigationStack{
Image("NFL_Logo")
.resizable()
List(items, children: \.items) {row in
NavigationLink{
NFLTeamRosterView(teamName : row.name, teamCode: row.teamCode, userAllRosters : userAllRosters)
} label: {
Text(row.name)
}
.disabled(!row.showTeam)
}
}
}
}
}
extension Team {
static let rai = Team(name:"Raiders", icon:"RAI_Logo", teamCode:"rai", showTeam:true)
static let rav = Team(name:"Ravens", icon:"BAL_Logo", teamCode:"rav", showTeam:true)
static let mia = Team(name:"Dolphins", icon:"MIA_Logo", teamCode:"mia", showTeam:true)
static let buf = Team(name:"Bills", icon:"BUF_Logo", teamCode:"buf", showTeam:true)
static let nwe = Team(name:"Patriots", icon:"NWE_Logo", teamCode:"nwe", showTeam:true)
static let nyj = Team(name:"Jets", icon:"NYJ_Logo", teamCode:"nyj", showTeam:true)
static let cin = Team(name:"Bengals", icon:"CIN_Logo", teamCode:"cin", showTeam:true)
static let pit = Team(name:"Steelers", icon:"PIT_Logo", teamCode:"pit", showTeam:true)
static let cle = Team(name:"Browns", icon:"CLE_Logo", teamCode:"cle", showTeam:true)
static let jax = Team(name:"Jaguars", icon:"JAX_Logo", teamCode:"jax", showTeam:true)
static let oti = Team(name:"Titans", icon:"OTI_Logo", teamCode:"oti", showTeam:true)
static let clt = Team(name:"Colts", icon:"CLT_Logo", teamCode:"clt", showTeam:true)
static let htx = Team(name:"Texans", icon:"HTX_Logo", teamCode:"htx", showTeam:true)
static let kan = Team(name:"Chiefs", icon:"KAN_Logo", teamCode:"kan", showTeam:true)
static let sdg = Team(name:"Chargers", icon:"SDG_Logo", teamCode:"sdg", showTeam:true)
static let den = Team(name:"Broncos", icon:"DEN_Logo", teamCode:"den", showTeam:true)
static let AFCWest = Team(name: "AFC West", icon: "NFL_Logo", teamCode:"AFCW", showTeam:false, items: [Team.rai, Team.kan, Team.sdg, Team.den])
static let AFCNorth = Team(name: "AFC North", icon: "NFL_Logo", teamCode:"AFCN", showTeam:false, items: [Team.rav, Team.pit, Team.cle, Team.cin])
static let AFCSouth = Team(name: "AFC South", icon: "NFL_Logo", teamCode:"AFCS", showTeam:false, items: [Team.jax, Team.oti, Team.htx, Team.clt])
static let AFCEast = Team(name: "AFC East", icon: "NFL_Logo", teamCode:"AFCE", showTeam:false, items: [Team.nwe, Team.mia, Team.nyj, Team.buf])
}
For background, NFLTeamRosterView is designed to accept any team, not an AFC division input, thus the reason for it being disabled as a selectable list item. Any time I make a call to this view though (in particular I'm showing a sheet with NFLView(userPlayEstimates: userPlays, userAllRosters: userRosters)
, I get an immediate error from NFLTeamRosterView- it's being called on my first list item - NFLTeamRosterView(teamName : "AFC North", teamCode : "AFCN")
Obviously this is a problem in that it causes issues I'd have to design around, but does it also mean that any time I'm creating this nested list that every navigationLink is being run? This seems like a pretty big computation drain if so, and is there a way to prevent that from happening?
答案1
得分: 0
这是在SwiftUI
中的预期行为。你可以尝试使用if/else
来替代禁用链接:
struct NFLView: View {
var userPlayEstimates: UserPlayData
var userAllRosters: userAllRosters
let items: [Team] = [.AFCNorth, .AFCSouth, .AFCEast, .AFCWest]
var body: some View {
VStack {
NavigationStack {
Image("NFL_Logo")
.resizable()
List(items, children: \.items) { row in
if row.showTeam {
NavigationLink {
NFLTeamRosterView(teamName: row.name, teamCode: row.teamCode, userAllRosters: userAllRosters)
} label: {
Text(row.name)
}
} else {
Text(row.name)
}
}
}
}
}
}
希望对你有帮助!
英文:
This is expected behaviour in SwiftUI
. You could try using if/else
instead of disabling the link:
struct NFLView: View {
var userPlayEstimates : UserPlayData
var userAllRosters : userAllRosters
let items: [Team] = [.AFCNorth, .AFCSouth, .AFCEast,.AFCWest]
var body: some View {
VStack{
NavigationStack{
Image("NFL_Logo")
.resizable()
List(items, children: \.items) { row in
if row.showTeam {
NavigationLink{
NFLTeamRosterView(teamName : row.name, teamCode: row.teamCode, userAllRosters : userAllRosters)
} label: {
Text(row.name)
}
} else {
Text(row.name)
}
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论