NavigationLink onTapGesture 和导航未始终触发
Posted
技术标签:
【中文标题】NavigationLink onTapGesture 和导航未始终触发【英文标题】:NavigationLink onTapGesture and navigation not firing consistently 【发布时间】:2020-03-21 06:14:54 【问题描述】:在 SwiftUI 视图中,我通过创建一个包含包含一些文本的 NavigationView 的 VStack 来实现垂直滚动列表。我通过循环遍历popularFeedTypes 对象来构建它,为popularFeedTypes 对象中的每个项目创建一个NavigationLink。如果用户单击 NavigationLink,则用户将被推送到名为 FeedTypeView 的新视图。你可以看下面的代码。
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)
我遇到的问题是,如果我在 NavigationLink 上有一个 onTapGesture 操作,我会在模拟器中体验到不同的行为,具体取决于我单击该行的方式。如果我单击该行右侧的文本或箭头 (>),onTapGesture 会触发,但不会发生导航。如果我单击文本和箭头之间的空间,onTapGesture 不会触发,但会发生导航。如果我删除 onTapGesture 代码,单击三个位置中的任何一个都会导致导航发生。所以我的问题是即使存在 onTapGesture 操作也不应该发生导航吗?无论您单击构成 NavigationLink 的行的位置,onTapGesture 操作也不应该触发吗?
【问题讨论】:
NavigationLink 本质上是一个按钮,因此它会响应触摸,当您在其上添加点击手势时,您将拥有一个试图同时响应两个触摸的视图。点击手势有什么用?也许它可以以更好的方式实现? 希望根据用户点击查询一些数据并将其加载到环境对象中 为什么不在目的地的 onApear() 中启动它? 我想这也可以,我想我需要在进行下一个视图之前做出一些决定,但这可能可以用另一种方式处理。不过,我仍然很好奇,是否可以在导航到另一个视图之前在单击期间触发自定义逻辑。 处理各种触摸非常棘手。您还可以在带有isActive
标志的EmptyView
上使用Button
和NavaigationLinink
。然后您可以在Button
的操作中处理您想要在onTapGesture
中处理的任何事情,并将isActive
设置为true 作为最后一件事。
【参考方案1】:
您可以使用 onAppear 来处理点击事件。
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)
【讨论】:
【参考方案2】:如果您想同时执行操作和导航,您可以这样做:
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)
【讨论】:
不幸的是,这并没有解决我的问题,但听起来很有希望 这个解决方案如何为您工作?我试过了,还是不行 谢谢!在最新的 Swift/SwiftUI 上对我来说就像一个魅力。我使用 LazyVStack 而不是 List,所以它可能是相关的。【参考方案3】: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)
这应该可行。在NavigationLink
上使用simultaneousGesture
【讨论】:
应该工作吗?你试过了吗?它不适合我。 @MatheusCâmara - 此代码对我有用。【参考方案4】:如果你想在你的导航链接被触发之前做一些事情,你可以用tag
和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)
【讨论】:
以上是关于NavigationLink onTapGesture 和导航未始终触发的主要内容,如果未能解决你的问题,请参考以下文章
如何将 ContextMenu 与 NavigationLink 一起使用?