2

I want to do two things. Firstly, I want to navigate to SpaceView if I tap on 'TileCell'.

NavigationLink(destination: SpaceView(space: space)) {
        TileCell(
            image: image,
            text: space.name!,
            detailText: nil,
            isFaded: space.isComplete
        )
    }
    .buttonStyle(PlainButtonStyle())
}

This works great.

But I also want to long press on TileCell to trigger a different action.

NavigationLink(destination: SpaceView(space: space)) {
        TileCell(
            image: image,
            text: space.name!,
            detailText: nil,
            isFaded: space.isComplete
        )
        .onLongPressGesture {
            action()
        }
    }
    .buttonStyle(PlainButtonStyle())
}

The long-press gesture works, but I can no longer navigate to SpaceView by tapping.

Any help getting both to work would be appreciated.

bobby123uk
  • 892
  • 4
  • 17
  • Does this answer your question https://stackoverflow.com/a/61865823/12299030? Also next might be helpful https://stackoverflow.com/a/58898046/12299030. – Asperi Dec 09 '20 at 04:27

2 Answers2

2

I would suggest manually triggering the NavigationLink with isActive Binding in the onTapGesture. Then you can handle on tap and long press.

struct ContentView: View {
    
    @State var outputText: String = ""
    @State var isActive : Bool = false
    var body: some View {
        NavigationView {
            NavigationLink(destination: SpaceView(), isActive: $isActive) { //<< here use isActive
                TileCell()
                    .onTapGesture {
                        isActive = true //<< activate navigation link manually
                    }
                    .onLongPressGesture {
                        print("Long press") //<< long press action here
                    }
            }
        }
    }
}
davidev
  • 7,694
  • 5
  • 21
  • 56
  • I found an issue with this approach. If you setup a forEach and have a TileCell for each element in a collection, upon selection, the destination displays for some other element (not the one you selected). – bobby123uk Dec 11 '20 at 09:44
0

Building off davidev's answer, here's a version that works with multiple NavigationLinks created with ForEach

struct ContentView: View {
    @State var tileTextArray = ["Tile 1", "Tile 2", "Tile 3"]
    @State var isActiveArray = [false, false, false]
    
    var body: some View {
        NavigationView {
            ForEach(tileTextArray.indices, id: \.self) { index in
                NavigationLink(destination: SpaceView(), isActive: $isActiveArray[index]) { //<< here use isActive
                    TileCell()
                        .onTapGesture {
                            isActiveArray[index] = true //<< activate navigation link manually
                        }
                        .onLongPressGesture {
                            print("Long press") //<< long press action here
                        }
                }
            }
        }
    }
}
Dylan
  • 545
  • 4
  • 15