我正试图在SwiftUI的许多社交媒体应用程序中重现账户关注者流量.

  1. 你只需按下个人资料上的按钮,即可查看你的关注者列表
  2. 你可以点击你的任何一个关注者来查看他们的账户
  3. 您可以按下他们个人资料上的按钮来查看他们的关注者列表
  4. 你可以点击他们的任何一个关注者来查看他们的账户

步骤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]!
}

推荐答案

我设法通过创建一个Options枚举来解决了这个问题.

enum Options: Hashable {
    case destination(Int)
}

MyProfileView中,添加.navigationDestination个修改器,使其位于重复视图之外.

.navigationDestination(for: UserInfoPreview.self) { userInfoPreview in
    UserInfoView(id: userInfoPreview.id)
}
.navigationDestination(for: Options.self) { destination in
    switch destination {
    case .destination(let userID): FollowersList(id: userID)
    }
}

SomeProfileView中更新了NavigationLink.

NavigationLink("See followers", value: Options.destination(id))

也从视图中删除了路径绑定.

Swift相关问答推荐

我应该在自定义存储队列上使用弱self 吗?

VisionOS发送通知

传递给SWIFT ResultBuilder的闭包中结果类型的对象

RxSwift .debounce,.throttle用于分页

如何写一个;风格;视图修饰符,它会影响特定类型的所有嵌套视图?

使 tabview 垂直将视图移动到右侧 swift ui

快速并行读取进程 standardOutput 和 standardError 而不会阻塞

循环字典中的数组

使用`JSONSerialiser`时,省略通用可选项

If 语句在 Swift 中有 2 个日期

deinitialize() 与 deallocate()

Swift-SceneKit-无法从art.scnassets加载.scn文件

SwiftUI:决定键盘重叠的内容

数组使用偏移量对自身执行 XOR

如何 for each 用户制作一个单独的按钮,以便在按下它时切换 isFollowingUser Bool 并更改为关注?

如何以快速 Select 器菜单样式调整图像大小

通用枚举菜单 SwiftUI

在 SwiftUI 中,如何在 UIView 内或作为 UIView 使用 UIHostingController?

iOS/Swift:如何检测 UITextField 上的touch 动作

playground 导入:没有这样的模块Foo