如何在另一个 NavigationLink 中有一个 NavigationLink
Posted
技术标签:
【中文标题】如何在另一个 NavigationLink 中有一个 NavigationLink【英文标题】:How to have a NavigationLink inside another NavigationLink 【发布时间】:2020-08-24 08:05:27 【问题描述】:我和我的团队目前正在用 SwiftUI 开发一个 Mastodon 客户端,我有一个简单的 StatusView,用于显示所有帖子数据,目前看起来像这样:
这个视图,在我的项目中称为StatusView
,有两个NavigationLinks
:主要的一个,将用户重定向到帖子的线程,一个将用户重定向到帖子的作者个人资料,当帖子的个人资料图片时被点击。
到这里为止,一切正常。如果您点击帖子上不是按钮(例如、提升和分享)或个人资料图片的任何地方,它会打开该主题。如果您点击个人资料图片,则会打开作者的个人资料。
但是,如果您点击下方个人资料图片,应用会崩溃,只会出现以下错误:
2020-08-23 21:32:39.929392-0400 Hyperspace[830:147862] WF: _WebFilterIsActive returning: NO
2020-08-23 21:32:40.117865-0400 Hyperspace[830:147862] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo=NSLocalizedFailureReason=Specified target process does not exist>
2020-08-23 21:32:40.117994-0400 Hyperspace[830:147862] [ProcessSuspension] 0x11decfa80 - ProcessAssertion: Failed to acquire RBS Background assertion 'WebProcess Background Assertion' for process with PID 837, error: Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo=NSLocalizedFailureReason=Specified target process does not exist
2020-08-23 21:32:40.119401-0400 Hyperspace[830:147862] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo=NSLocalizedFailureReason=Specified target process does not exist>
2020-08-23 21:32:40.119549-0400 Hyperspace[830:147862] [ProcessSuspension] 0x11decfac0 - ProcessAssertion: Failed to acquire RBS Suspended assertion 'WebProcess Suspended Assertion' for process with PID 837, error: Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo=NSLocalizedFailureReason=Specified target process does not exist
Fatal error: UIKitNavigationBridge: multiple active destinations: file SwiftUI, line 0
2020-08-23 21:32:40.292135-0400 Hyperspace[830:147862] Fatal error: UIKitNavigationBridge: multiple active destinations: file SwiftUI, line 0
我猜这是因为当你点击那里时,线程和个人资料的导航链接都被触发,导致应用程序崩溃,因为有多个活动目的地,因为它试图转到线程和个人资料同一时间。
TL;DR
我的应用程序崩溃了,因为两个 NavigationLink 在它们不应该被同时触发的时候被触发了。我该如何解决这个问题?
提前致谢。
我的代码
/// The status is being displayed in a ``StatusList``, so we should make it smaller and more compact.
private struct CompactStatusView: View
/// The ``Status`` data model from where we obtain all the data.
var status: Status
/// Used to trigger the navectigationLink to redirect the user to the thread.
@Binding var goToThread: Bool
/// Used to redirect the user to a specific profile.
@Binding var profileViewActive: Bool
var body: some View
ZStack
self.content
.padding(.vertical, 5)
.contextMenu(
ContextMenu(menuItems:
Button(action: , label:
Label("Report post", systemImage: "flag")
)
Button(action: , label:
Label("Report \(self.status.account.displayName)", systemImage: "flag")
)
Button(action: , label:
Label("Share as Image", systemImage: "square.and.arrow.up")
)
)
)
.buttonStyle(PlainButtonStyle())
.navigationBarHidden(self.profileViewActive)
var content: some View
HStack(alignment: .top, spacing: 12)
URLImage(URL(string: self.status.account.avatarStatic)!,
placeholder: _ in
Image("amodrono")
.resizable()
.scaledToFit()
.clipShape(Circle())
.frame(width: 50, height: 50)
.redacted(reason: .placeholder)
,
content:
$0.image
.resizable()
.scaledToFit()
.clipShape(Circle())
.frame(width: 50, height: 50)
)
.onTapGesture
self.profileViewActive.toggle()
.background(
NavigationLink(
destination: ProfileView(
accountInfo: ProfileViewModel(
accountID: self.status.account.id
),
isParent: false
),
isActive: self.$profileViewActive
)
Text("")
.frame(width: 0, height: 0)
)
VStack(alignment: .leading, spacing: 2)
HStack(alignment: .firstTextBaseline)
if !self.status.account.displayName.isEmpty
Text("\(self.status.account.displayName)")
.font(.headline)
.lineLimit(1)
Text("@\(self.status.account.acct)")
.foregroundColor(.secondary)
.lineLimit(1)
Text("· \(self.status.createdAt.getDate()!.getInterval())")
.foregroundColor(.secondary)
.lineLimit(1)
StatusViewContent(
isMain: false,
content: self.status.content,
card: self.status.card,
attachments: self.status.mediaAttachments,
goToProfile: self.$profileViewActive
)
StatusActionButtons(
isMain: false,
repliesCount: self.status.repliesCount,
reblogsCount: self.status.reblogsCount,
favouritesCount: self.status.favouritesCount,
statusUrl: self.status.uri
)
.onTapGesture
self.goToThread.toggle()
.background(
NavigationLink(
destination: ThreadView(
mainStatus: self.status
),
isActive: self.$goToThread
)
EmptyView()
)
Spacer()
我想这里的重要部分是:
个人资料图片:
URLImage(URL(string: self.status.account.avatarStatic)!,
placeholder: _ in
Image("amodrono")
.resizable()
.scaledToFit()
.clipShape(Circle())
.frame(width: 50, height: 50)
.redacted(reason: .placeholder)
,
content:
$0.image
.resizable()
.scaledToFit()
.clipShape(Circle())
.frame(width: 50, height: 50)
)
.onTapGesture
self.profileViewActive.toggle()
.background(
NavigationLink(
destination: ProfileView(
accountInfo: ProfileViewModel(
accountID: self.status.account.id
),
isParent: false
),
isActive: self.$profileViewActive
)
Text("")
.frame(width: 0, height: 0)
)
最后两个修饰符
.onTapGesture
self.goToThread.toggle()
.background(
NavigationLink(
destination: ThreadView(
mainStatus: self.status
),
isActive: self.$goToThread
)
EmptyView()
)
【问题讨论】:
【参考方案1】:这里是一些复制场景的可能解决方案的演示(因为提供的代码不能按原样测试)。这个想法是重用一个 NavigationLink,但根据激活位置不同的目的地。
使用 Xcode 12 / ios 14 测试
struct DemoRowView: View
@State private var isProfile = false
@State private var isActive = false
var body: some View
HStack
Image(systemName: "person")
.scaledToFit()
.onTapGesture
self.isProfile = true
self.isActive = true
Text("Thread description")
.onTapGesture
self.isProfile = false
self.isActive = true
.background(
NavigationLink(destination: self.destination(), isActive: $isActive) EmptyView()
)
.buttonStyle(PlainButtonStyle())
@ViewBuilder
private func destination() -> some View
if isProfile
ProfileView()
else
ThreadView()
【讨论】:
谢谢!多么简单的解决方案,我不能再笨了......?以上是关于如何在另一个 NavigationLink 中有一个 NavigationLink的主要内容,如果未能解决你的问题,请参考以下文章
NavigationLink SwiftUI 中的三元运算符
我在同一个类中有 2 个函数,我想在一个函数中修改向量的大小,并在另一个函数中有这个新大小?
从目标视图返回时,SwiftUI NavigationLink 显示为突出显示