You can add a contentShape
modifier to tell the system how to do hit testing for the NavigationLink:
NavigationLink(destination: Text("DetailView")){
Triangle()
.fill(Color.green)
.frame(width: 100, height: 100, alignment: .center)
}
.contentShape(Triangle())
There's a caveat here, which is SwiftUI includes some slop in the hit testing, so this will still accept some clicks/touches that are close to the borders of the shape, but still outside. I don't have a great solution for getting rid of that slop. But, you can see that the same thing happens on the basic Rectangle
that normally makes up the navigation view as well -- e.g. put a border
around it and note that you can still tap slightly outside of that border.
A secondary way you could experiment with is render the Path
on its own, attach an onTapGesture
to it and turn on/off a boolean connected to the NavigationLink
that you'd then want to move outside your hierarchy. Something like:
struct ContentView: View {
@State var navigationLinkActive = false
var body: some View {
NavigationView {
Group {
if navigationLinkActive {
NavigationLink(destination: Text("Detail"), isActive: $navigationLinkActive) {
EmptyView()
}
}
Triangle()
.fill(Color.green)
.frame(width: 100, height: 100, alignment: .center)
.onTapGesture {
navigationLinkActive = true
}
}.navigationBarTitle(Text("Triangle"))
EmptyView()
}
}
}
Note that in this solution, you still have the hit slop issue, plus you lose the touch down/up highlighting that the Button
has.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…