1

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!

Muz
  • 699
  • 1
  • 11
  • 25
  • Another answer of @Asperi may help to make it above. https://stackoverflow.com/questions/58897453/how-to-perform-an-action-after-navigationlink-is-tapped – Muz May 17 '20 at 04:47

2 Answers2

1

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")
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Thank you very much. It is really a cool method I have not known before! I have updated the question. Could you please check it again? – Muz May 16 '20 at 18:58
  • 1
    @garyyong, one question - one answer, next time formulate your needs more precisely. – Asperi May 16 '20 at 19:04
  • I will check it next time. I have tried many times to change the NavigationLink's position such as in or out the `ForEach` or `List`, but it still not work. It seems `simultaneousGesture` cannot work on the element of a `List` – Muz May 17 '20 at 02:48
0

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")
    }
}
Muz
  • 699
  • 1
  • 11
  • 25
  • Does anyone know how to solve the the little bug above? The code of the bug is commented. – Muz May 17 '20 at 05:06