Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI List disclosure indicator without NavigationLink

I am searching for a solution to show the disclosure indicator chevron without having the need to wrap my view into an NavigationLink. For example I want to show the indicator but not navigate to a new view but instead show a modal for example.

I have found a lot solutions that hide the indicator button but none which explains how to add one. Is this even possible in the current SwiftUI version ?

struct MyList: View {
    var body: some View {
        NavigationView {
        List {
            Section {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
                Text("Item 4")

            }
        }
    }
}

For example I want to add the disclosure indicator to Item 1 without needing to wrap it into an NavigationLink

I already tried to fake the indicator with the chevron.right SF Symbol, but the symbol does not match 100% the default iOS one. Top is default bottom is chevron.right.

Disclosure Button Image

like image 608
grahan Avatar asked Jun 06 '20 22:06

grahan


People also ask

How to hide disclosure indicator in SwiftUI List?

We will start by replacing List body with a ZStack and move NavigationLink inside the ZStack . Next, we will set the ZStack alignment to leading and add opacity modifier with 0.0 value to the NavigationLink . Build and run: Notice that the disclosure indicator is not there anymore.

How to hide NavigationLink in SwiftUI?

Basically using a ZStack we layered the item. So within the ZStack the first backside item is the NavigationLink line 20, and the top item is a HStack line 26. The HStack contains a Text view and it hides the backside NavigationLink view.

How do I use navigation in SwiftUI?

Start by creating a new SwiftUI View file to create your alternative master view. Name it ArtTabView. swift. Next, copy all the code inside ContentView — not the struct ContentView line or the closing brace — and paste it inside the struct ArtTabView closure, replacing the boilerplate body code.


2 Answers

Hopefully, this is what you are looking for. You can add the item to a HStack and with a Spacer in between fake it that its a Link:

HStack {
                    Text("Item 1")
                    Spacer()
                    Button(action: {

                    }){
                        Image(systemName: "chevron.right")
                            .font(.body)
                    }
                }
like image 134
Geart Otten Avatar answered Sep 19 '22 23:09

Geart Otten


It is definitely possible.

You can use a combination of Button and a non-functional NavigationLink to achieve what you want.

Add the following extension on NavigationLink.

extension NavigationLink where Label == EmptyView, Destination == EmptyView {

   /// Useful in cases where a `NavigationLink` is needed but there should not be
   /// a destination. e.g. for programmatic navigation.
   static var empty: NavigationLink {
       self.init(destination: EmptyView(), label: { EmptyView() })
   }
}

Then, in your List, you can do something like this for the row:

// ...
ForEach(section.items) { item in
    Button(action: {
        // your custom navigation / action goes here
    }) {
        HStack {
            Text(item.name)
            Spacer()
            NavigationLink.empty
        }
    }
 }
 // ...

The above produces the same result as if you had used a NavigationLink and also highlights / dehighlights the row as expected on interactions.

like image 29
George Marmaridis Avatar answered Sep 20 '22 23:09

George Marmaridis