UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: How do I disable a SwiftUI NavigationView list item row on load?

Forums > SwiftUI

Hello

I have an array of objects (employees) that I am displaying in a navigationview. Each object has a boolean property called "Active". If the employee is active I want the navigationlink for that list item to work as it normally would but if the employee is not active then I want that list item to be disabled so that the navigationlink or any swipe actions do not work. This is my code:

NavigationView {
        List {
            CustomSearchBar(searchText: $searchText, searchCategory: $searchCategory)
            ForEach(Employees) { person in
                ZStack {
                    NavigationLink(destination: DisplayDetails().environmentObject(person)) {
                        ListItem().environmentObject(person)
                    }
                }
                .swipeActions(edge: .leading, content: {
                    Button {
                        Employees.toggleArchiveFlag(for: person.id)
                    } label: { 
                        Label("Archive", systemImage: !person.archived ? "square.and.arrow.down" : "trash")
                    }
                    .tint(!person.archived ? .blue : .red)
                })
                .disabled(!person.active)
            }
        }
        .navigationTitle("Current Employees")
        .padding(.horizontal,-15) // remove the padding that the list adds to the screen
    }

What ends up happing is that when the view initially loads everything is enabled regardless of each employee's active status. But if I click any of the navigationlinks to load the "DisplayDetails" detailed view and then return back to the main navigationview OR if I click on any of the searchbar toggles or use the searchbar to filter my list of people then the view updates and the correct people are disabled.

It is almost as if the statement ".disabled(!person.active)" is being called too late. If that is the case then where should I be calling it? I have tried moving that statement in the following places:

  • The closing bracket of the Zstack. But this does nothing
  • Right below the "ListItem().environmentObject(person)" statement but this still shows the same behavior as mentioned earlier and when the navigationlink is eventually disabled then the swipeactions are still enabled.

Any help at all would be appreciated!

2      

Copy this into a new project. Run it!

Is this what you're trying to achieve?

//  DisableLinkView.swift
//  Disable a Navigation Link based on an employee's status
//  Created by Obelix on 2/9/22.
//
import SwiftUI

// Sample employee struct
struct Employee: Identifiable {
    let id =      UUID()
    let name:     String
    let isActive: Bool
}

struct DisableLinkView: View {
    @State private var employees = [
        Employee(name: "Obelix",   isActive: true ),
        Employee(name: "Bronco",   isActive: true ),
        Employee(name: "Hermione", isActive: false),
        Employee(name: "Luna",     isActive: true )
    ]

    var body: some View {
        VStack {
            // List for debugging
            ForEach(employees) { person in
                Text( "\(person.name) is \(person.isActive ? "active" : "inactive")")
            }.padding(.bottom)
            NavigationView {
                List{
                    ForEach(employees) { person in
                        NavigationLink(destination: Text(person.name)) {
                            Text(person.name)
                        }
                        .padding()
                        .disabled(!person.isActive) // Diable the link if not active
                        .background(person.isActive ? .clear : .red.opacity(0.15))

                    }
                } .navigationTitle("Employees")
            }
        }
    }
}

2      

@Obelix thanks for the reply. Your code helped me to see where the problem in mine was. The issue that I had was not with where I was disabling the list item but the criteria that I was using to set person.isActive to either true or false

Thank-you for taking the time to post!

2      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.