Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SwiftUI nested list calls navigationLink prior to selection

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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)
                    }
                }
            }  
        }
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading