Muz
Muz

Reputation: 759

How to change NavigationView's destination in SwiftUI?

The need is to go to View1 by default and when onLongPressGesture to View2. @State is used to make it. And the code is as following:

@State var showingView2 = false

if self.showingView2 {
    NavigationLink(destination: View2())
    { Cell(name: View2.name)
        .onLongPressGesture(minimumDuration: 1) {
            self.showingView2 = true
        }
    }

} else {
    NavigationLink(destination: View1())
    { Cell(name: View1.name)
        .onLongPressGesture(minimumDuration: 1) {
            self.showingView2 = true
        }
    }

}

For the simplicity, new button cannot be added in the UI. I know the code cannot run, but I do not know how to fix it.

Any suggestion will help me. Thanks!

=========================================

Updated

Thanks for @Asperi!

But in my project there is ForEach in NavigationView, in which case the answer does not work. The code is following:

import SwiftUI

struct ContentView: View {

    @State private var isLongPressed = false

    let lyrics = ["a", "b", "c"]

    var body: some View {
        NavigationView {
            List() {
                ForEach(0..<lyrics.count) { (index) in
                    NavigationLink(destination:
                        Group {
                            if self.isLongPressed { Destination2() }
                                else { Destination1() }
                        })
                        { Text(self.lyrics[index]) }
                        .simultaneousGesture(LongPressGesture(minimumDuration: 1).onEnded { flag in
                            self.isLongPressed.toggle()
                    })
                }
            }
        }
    }
}

struct Destination1: View {
    var body: some View {
        Text("Destination1")
    }
}

struct Destination2: View {
    var body: some View {
        Text("Destination2")
    }
}

Then how to make it in this case? And I do not want to change the short tap or long tap's function, just short tap to View1 and long tap to View2. Thanks!

Upvotes: 1

Views: 838

Answers (2)

Muz
Muz

Reputation: 759

Here is the final answer based on @Asperi.

And there is still a little bug. If not add many space in the NavigationLink's name, the long tap only work when you tap on the "a" "b" "c". On other space of the NavigationLink out of the "a" "b" "c", all tap is short tap.

import SwiftUI

struct ContentView: View {

    @State private var isLongPressed = false
    @State var currentTag: Int?

    let lyrics = ["a", "b", "c"]

    var body: some View {
        NavigationView {

            List {

                ForEach(0..<lyrics.count) { index in
                    VStack{
                        HStack(alignment: .top) {
                           NavigationLink(destination: Group
                                { if self.isLongPressed { Destination2() } else { Destination1() } }, tag: index, selection: self.$currentTag
                            ) {

// This is still a little bug. If not add many space, the long tap only work when you tap on the "a" "b" "c". On other space of the NavigationLink out of the "a" "b" "c", all tap is short tap.

                                Text(self.lyrics[index] + "                           ")
                            }


                        }
                    }.simultaneousGesture(LongPressGesture().onEnded { _ in
                        print("Got Long Press")
                        self.currentTag = index
                        self.isLongPressed = true
                            })
                    .simultaneousGesture(TapGesture().onEnded{
                        print("Got Tap")
                        self.currentTag = index
                        self.isLongPressed = false
                    })
                    .onAppear(){
                        self.isLongPressed = false
                    }

                }
            }
        }
    }
}


struct Destination1: View {
    var body: some View {
        Text("Destination1")
    }
}

struct Destination2: View {
    var body: some View {
        Text("Destination2")
    }
}

Upvotes: 0

Asperi
Asperi

Reputation: 257711

Here is a demo of possible approach. Tested with Xcode 11.4 / iOS 13.4

demo

struct TestAlternateDestinations: View {
    @State private var isLongPressed = false

    var body: some View {
        NavigationView {
            NavigationLink(destination: Group {
                if isLongPressed { Destination2() }
                    else { Destination1() }}) {
                Text(self.isLongPressed ? "Link2" : "Link1")
            }
            .simultaneousGesture(LongPressGesture(minimumDuration: 1).onEnded { flag in
                self.isLongPressed.toggle()
            })
        }
    }
}

struct Destination1: View {
    var body: some View {
        Text("Destination1")
    }
}

struct Destination2: View {
    var body: some View {
        Text("Destination2")
    }
}

Upvotes: 1

Related Questions