Reputation: 2352
In a SwiftUI view I implemented a vertically scrolling list by creating a VStack that contains a NavigationView that contains some text. I build this by looping through a popularFeedTypes object creating a NavigationLink for each item in the popularFeedTypes object. If a user clicks on the NavigationLink the user is pushed to a new view called FeedTypeView. You can see the code below.
VStack{
NavigationView{
List (self.popularFeedTypes.popularFeedTypes!, id: \.self) { feedType in
NavigationLink(destination: FeedTypeView(feedType: feedType)) {
Text(feedType.feedType)
}.onTapGesture {
print("TAPPED")
}
}
.navigationBarTitle(Text("Discover"), displayMode: .inline)
}
}
The problem I am experiencing is that if I have an onTapGesture action on the NavigationLink, I experience a different behavior from within the simulator depending upon how I click the row. If I click on the text or on the arrow (>) at the right hand side of the row, the onTapGesture fires off but no navigation occurs. If I click on the space between the text and the arrow, onTapGesture does not fire but navigation occurs. If I remove the onTapGesture code, clicking any of the three places causes navigation to occur. So my question is shouldn't navigation occur even with an onTapGesture action existing? Also shouldn't the onTapGesture action fire off regardless of where you click on the row that makes up the NavigationLink?
Upvotes: 10
Views: 12361
Reputation: 9979
VStack {
NavigationView{
List (self.popularFeedTypes.popularFeedTypes!, id: \.self) { feedType in
NavigationLink(destination: FeedTypeView(feedType: feedType)) {
Text(feedType.feedType)
}
.simultaneousGesture(TapGesture().onEnded {
print("TAPPED")
})
.buttonStyle(PlainButtonStyle())
}
.navigationBarTitle(Text("Discover"), displayMode: .inline)
}
}
This should work. use simultaneousGesture
on NavigationLink
Upvotes: 7
Reputation: 3964
You can use onAppear to handle tapped event.
VStack {
NavigationView {
List(self.popularFeedTypes.popularFeedTypes!, id: \.self) { feedType in
NavigationLink(
destination: FeedTypeView(feedType: feedType).onAppear { print("TAPPED") }) {
Text(feedType.feedType)
}
}
.navigationBarTitle(Text("Discover"), displayMode: .inline)
}
}
Upvotes: 6
Reputation: 2094
If you want to do something before your navigation link is triggered, you can initialize a navigation link with tag
and selection
.
struct someViewName: View {
@State var navigationLinkTriggerer: Bool? = nil
@State var navigationLinkFeedType: FeedType
var body: some View {
VStack {
NavigationLink(destination: FeedTypeView(feedType: navigationLinkFeedType),
tag: true,
selection: $navigationLinkTriggerer) {
EmptyView()
}
NavigationView {
List (self.popularFeedTypes.popularFeedTypes!, id: \.self) { feedType in
Button(feedType) {
// do all you want here
print("TAPPED")
// then set the navigationLinkTriggerer to value of you navigation link `tag`
// in this case tag is equal to `true`
// this will trigger the navigation link
self.navigationLinkFeedType = feedType
self.navigationLinkTriggerer = true
}
}
.navigationBarTitle(Text("Discover"), displayMode: .inline)
}
}
}
}
Upvotes: 0
Reputation: 117
If you want to perform both action and navigation simultaneously you can do this:
VStack{
NavigationView{
List (self.popularFeedTypes.popularFeedTypes!, id: \.self) { feedType in
NavigationLink(destination: FeedTypeView(feedType: feedType)) {
Text(feedType.feedType)
}
.simultaneousGesture(TapGesture().onEnded{
print("TAPPED")
})
}
.navigationBarTitle(Text("Discover"), displayMode: .inline)
}
}
Upvotes: 2