SwiftUI 上的 NavigationLink 两次推送视图
Posted
技术标签:
【中文标题】SwiftUI 上的 NavigationLink 两次推送视图【英文标题】:NavigationLink on SwiftUI pushes view twice 【发布时间】:2020-01-16 15:53:33 【问题描述】:在 SwiftUI 中添加 NavigationLink 时,目的地会出现两次,例如:我点击 NavigationLink 并推送我的目的地,但是当我通过后退按钮或滑动手势关闭目的地时,它会再次推送目的地而不点击链接。 这是我处理链接的代码部分:
var body: some View
HStack(spacing: 8.0)
ForEach(part.getReference()) (imageRef: ReferenceImage) in
ZStack(alignment: .topTrailing)
Image(uiImage: imageRef.getUIImage())
.resizable()
.frame(width: 90, height: 90)
.cornerRadius(6)
.onLongPressGesture
print("looong")
self.managedObjectContext.delete(imageRef)
do
try self.managedObjectContext.save()
catch
print("error deleting: \(error.localizedDescription)")
ZStack(alignment: .center)
Circle()
.foregroundColor(Color.appColors.lightRose)
.opacity(0.7)
.frame(width: 35, height: 35)
Image(systemName: "arkit")
.imageScale(.large)
NavigationLink(destination:
ZStack
Color.appColors.rose
.edgesIgnoringSafeArea(.top)
ReferenceARSwiftUIView(currentImage: imageRef.getUIImage())
.navigationBarTitle("AR Reference")
)
EmptyView()
.frame(width: 90, height: 90)
.animation(.interpolatingSpring(stiffness: 0.5, damping: 0.5))
编辑 01: 正如建议的那样,我删除了代码中的一些噪音:
var part: Part
var body: some View
HStack(spacing: 8.0)
ForEach(part.getReference()) (imageRef: ReferenceImage) in
ZStack(alignment: .topTrailing)
Image(uiImage: imageRef.getUIImage())
.resizable()
.frame(width: 90, height: 90)
.cornerRadius(6)
NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage()))
EmptyView()
.frame(width: 90, height: 90)
.animation(.interpolatingSpring(stiffness: 0.5, damping: 0.5))
编辑 02: 我想我缩小了范围,基本上如果我删除 ForEach,NavigationLink 会正确推送到下一个视图。此外,根据我在 ForEach 数组中的项目数量,推送的数量是相同的。
【问题讨论】:
您是否有机会在您的代码中删除和/或添加内容以便我们复制您的问题?您有几件事(Color.appColors.lightRose
、Image
、不需要的堆栈)确实会增加噪音。也许如果您将其剥离为 NavigationView
、NavigationLink
和 也许 ForEach
让我们复制您的问题,您可能会发现它正在工作......此时您可以添加回到其余部分,看看为什么您发布的代码不是。
好吧,我认为已经消除了代码中的大部分噪音??
我可能已经缩小了问题的范围,我在编辑 02 上解释了
谢谢,希望我没有冒犯你。两个想法。 (1) 我很少看到没有List
的ForEach
。这会有帮助吗? hackingwithswift.com/quick-start/swiftui/… 更多,(2)我积极检查这个网站的 SwiftUI 标签。我记得关于循环中List
和NavigationLink
(甚至Button
)行为的几个问题。你在这个网站上搜索过那些吗?事实是,我停止使用 NavigationView
和 List
的组合,因为...原始... SwiftUI 与 UIKit 相比,
我遇到了同样的问题。我相信在 ForEach 中使用 NavigationLink 时,SwiftUI 中可能存在错误。我无法让它与ScrollView
一起工作,如下所示。如果我不使用 ForEach,我只能让它工作。
【参考方案1】:
我确定Part
符合Identifiable
协议并具有id
属性。
NavigationLink
的目标被多次显示,因为在forEach
循环中有多个Part
实例具有完全相同的标识id
。
只要确保Part
的每个实例都有一个唯一的id
,一切都会按预期工作。
【讨论】:
hackingwithswift.com/books/ios-swiftui/…【参考方案2】:我通过将 NavigationLink 的标签设置为模型项的唯一 id 解决了这个问题。
假设你的 imageRef 有一个 ID,ReferenceImage 类。
var part: Part
var body: some View
HStack(spacing: 8.0)
ForEach(part.getReference()) (imageRef: ReferenceImage) in
ZStack(alignment: .topTrailing)
Image(uiImage: imageRef.getUIImage())
.resizable()
.frame(width: 90, height: 90)
.cornerRadius(6)
NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage()), tag: imageRef.id)
EmptyView()
.frame(width: 90, height: 90)
.animation(.interpolatingSpring(stiffness: 0.5, damping: 0.5))
NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage()), tag: imageRef.id)
【讨论】:
【参考方案3】:是的,将 List
更改为 ScrollView
在类似的情况下帮助了我。
ScrollView
if !usersViewModel.isLoading
ForEach(self.usersViewModel.users, id: \.id) user in
NavigationLink(destination: UserDashboardView(showDashboardDetail: $showDashboardDetail, user: user))
VStack(alignment: .leading)
NetworkCardView(user: user)
.frame(width: screen.size.width - 60, height: 250)
.padding(.top)
.listRowBackground(AppColor())
【讨论】:
【参考方案4】:我无法重现您的问题,因为即使是精简版也包含您声明的类型,但未包含在问题中。
有几点:
如果要使用NavigationLink
,则需要将视图嵌入NavigationView
。
如果您在HStack
中使用ForEach
,则可能会用完显示所有元素的空间,因此最好将其包装在ScrollView
中。
最后但同样重要的是:在ForEach
中,您必须将NavigationLink
设为您的***视图,并将任何其他视图设为其内容:
var body: some View
NavigationView
ScrollView(.horizontal)
HStack
ForEach(part.getReference()) (imageRef: ReferenceImage) in
NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage()))
Image(uiImage: imageRef.getUIImage())
.resizable()
.frame(width: 90, height: 90)
.cornerRadius(6)
【讨论】:
以上是关于SwiftUI 上的 NavigationLink 两次推送视图的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI NavigationLink 如何到达另一个 SwiftUI 页面?
SwiftUI:NavigationLink 内的水平 ScrollView 会中断导航