简体   繁体   中英

SwiftUI: Link together with NavigationLink as list item

How can one have a list where each item in the list contains a Link and a NavigationLink ?

When putting the Link and NavigationLink next to each other in an HStack both get triggered wherever I tap on the row.

struct ContentView: View {

    var body: some View {
        NavigationView {
            List {
                HStack {
                    Link(
                        "Link",
                        destination: URL(string: "https://www.apple.com")!
                    )
                    NavigationLink(
                        "Other View",
                        destination: Text("Hello from other view"))
                }
            }
        }
    }
}

Turns out the way Apple recommend to do this is to explicitly set the style on the Link button. eg

struct ContentView: View {

    var body: some View {
        NavigationView {
            List {
                HStack {
                    Link(
                        "Link",
                        destination: URL(string: "https://www.apple.com")!
                    )
                        .buttonStyle(.borderless) // <-- add this
                    NavigationLink(
                        "Other View",
                        destination: Text("Hello from other view"))
                }
            }
        }
    }
}

Answer based on excellent notes over here https://swiftui-lab.com/random-lessons/ . Do wish Apple would improve their SwiftUI docs!

Previous, it worked, but don't really recommend way of doing it by adding onTapGesture to the Link that explicity opens the URL. left below for context.

struct ContentView: View {
   
    @Environment(\.openURL) private  var openURL
    let url = URL(string: "https://www.apple.com")
    var body: some View {
        NavigationView {
            List {
                HStack {
                    
                    Link(
                        "Link",
                        destination: url!
                    )
                    .onTapGesture {
                        print("Opening URL \(url)")
                        openURL(url!)
                    }
                    
                    NavigationLink(
                        "Other View",
                        destination: Text("Hello from other view")
                    )
                }
            }
        }
    }
}

Based on shufflingb's answer:

Replace the link with a non-tappable element and add a gesture handler to it.

struct ContentView: View {

    @Environment(\.openURL) private  var openURL
    let url = URL(string: "https://www.apple.com")

    var body: some View {
        NavigationView {
            List {
                HStack {

                    Text("Link")
                        .foregroundColor(.accentColor)
                        .onTapGesture {
                            openURL(url!)
                        }

                    NavigationLink(
                        "Other View",
                        destination: Text("Hello from other view")
                    )
                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM