我正试图在SwiftUI的许多社交媒体应用程序中重现账户关注者流量.
- 你只需按下个人资料上的按钮,即可查看你的关注者列表
- 你可以点击你的任何一个关注者来查看他们的账户
- 您可以按下他们个人资料上的按钮来查看他们的关注者列表
- 你可以点击他们的任何一个关注者来查看他们的账户
步骤3和步骤4可以永远继续(下面的另一个示例):
MyProfile -> Followers (my followers list) -> FollowerView -> Followers (their followers list) -> FollowerView -> Followers (their followers list) -> FollowerView and so on...
但是,在运行时使用下面的实现,XCode控制台将打印:A navigationDestination for “myApp.SomeProfile” was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used.
我有一个理解,为什么这还不确定如何解决这个问题.我也会考虑作为NavigationLink
值的类型是否合适,因为它是Int
.用更定制的类型替换它会不会更好?
任何帮助都将不胜感激.
// Enum with custom options
enum ViewOptions: Hashable {
case followers(Int)
@ViewBuilder func view(_ path: Binding<NavigationPath>, id: Int) -> some View {
FollowersList(path: path, id: id)
}
}
// Root view
struct MyProfileView: View {
@State private var path: NavigationPath = .init()
var body: some View {
NavigationStack(path: $path) {
VStack {
Text(myProfile.username)
Button("See followers") {
path.append(ViewOptions.followers(myProfile.id))
}
.navigationDestination(for: ViewOptions.self) { option in
option.view($path, id: myProfile.id)
}
}
}
}
}
struct FollowersList: View {
@Binding var path: NavigationPath
var id: Int
var body: some View {
List(getFollowers(for: id), id:\.id) { follower in
NavigationLink(follower.username, value: follower)
}
.navigationDestination(for: SomeProfile.self) { profile in
switch profile.isMe {
case true: Text("This is your profile")
case false: SomeProfileView(path: $path, profile: profile)
}
}
}
}
struct SomeProfileView: View {
@Binding var path: NavigationPath
var profile: SomeProfile
var body: some View {
VStack {
Text(profile.username)
Button("See followers") {
path.append(ViewOptions.followers(profile.id))
}
}
}
}
// ----- Types & functions -----
// Example type for my profile
struct MyProfile: Identifiable, Hashable {
var id: Int
var username: String
}
// Example type for profiles reached via navigation link
// (can be my profile but with reduced functionality e.g. no follow button)
struct SomeProfile: Identifiable, Hashable {
var id: Int
var username: String
let isMe: Bool
}
// example myProfile (IRL would be stored in a database)
let myProfile = MyProfile(id: 0, username: "my profile")
// example users (IRL would be stored in a database)
let meVisited = SomeProfile(id: 0, username: "my profile reached from followers list", isMe: true)
let bob = SomeProfile(id: 1, username: "Bob", isMe: false)
let alex = SomeProfile(id: 2, username: "Alex", isMe: false)
// example user followers (IRL would be stored in a database)
let dict: [Int : [SomeProfile]] = [
0 : [bob, alex],
1 : [alex, meVisited],
2 : [alex, meVisited],
]
// example function to get followers of a user (IRL would be a network request)
func getFollowers(for id: Int) -> [SomeProfile] {
return dict[id]!
}