Sam*_*ies 4 ios swift swiftui swiftui-navigationlink swiftui-navigationstack
我正在尝试在 SwiftUI 中重新创建许多社交媒体应用程序中看到的帐户关注者流程。
\n步骤 3 和 4 可以永远继续下去(下面是另一个例子):
\nMyProfile -> Followers (my followers list) -> FollowerView -> Followers (their followers list) -> FollowerView -> Followers (their followers list) -> FollowerView and so on...\nRun Code Online (Sandbox Code Playgroud)\n然而,通过运行下面的实现,XCode 控制台会打印:
\n\n\n\xe2\x80\x9cmyApp.SomeProfile\xe2\x80\x9d 的 navigationDestination 已在堆栈的较早位置声明。仅使用最接近堆栈根视图声明的目标。
\n
我知道为什么会这样,但不确定如何解决这个问题。我也认为用作值的类型是否NavigationLink合适,因为它是Int。将其替换为更自定义的类型会更好吗?
任何帮助将不胜感激。
\n// Enum with custom options\nenum ViewOptions: Hashable {\n case followers(Int)\n \n @ViewBuilder func view(_ path: Binding<NavigationPath>, id: Int) -> some View {\n FollowersList(path: path, id: id)\n }\n}\n// Root view\nstruct MyProfileView: View {\n @State private var path: NavigationPath = .init()\n \n var body: some View {\n NavigationStack(path: $path) {\n VStack {\n Text(myProfile.username)\n Button("See followers") {\n path.append(ViewOptions.followers(myProfile.id))\n }\n .navigationDestination(for: ViewOptions.self) { option in\n option.view($path, id: myProfile.id)\n }\n }\n }\n }\n}\nstruct FollowersList: View {\n @Binding var path: NavigationPath\n var id: Int\n \n var body: some View {\n List(getFollowers(for: id), id:\\.id) { follower in\n NavigationLink(follower.username, value: follower)\n }\n .navigationDestination(for: SomeProfile.self) { profile in\n switch profile.isMe {\n case true: Text("This is your profile")\n case false: SomeProfileView(path: $path, profile: profile)\n }\n }\n }\n}\nstruct SomeProfileView: View {\n @Binding var path: NavigationPath\n \n var profile: SomeProfile\n var body: some View {\n VStack {\n Text(profile.username)\n Button("See followers") {\n path.append(ViewOptions.followers(profile.id))\n }\n }\n }\n}\n\n// ----- Types & functions -----\n\n// Example type for my profile\nstruct MyProfile: Identifiable, Hashable {\n var id: Int\n var username: String\n}\n// Example type for profiles reached via navigation link\n// (can be my profile but with reduced functionality e.g. no follow button)\nstruct SomeProfile: Identifiable, Hashable {\n var id: Int\n var username: String\n let isMe: Bool\n}\n// example myProfile (IRL would be stored in a database)\nlet myProfile = MyProfile(id: 0, username: "my profile")\n// example users (IRL would be stored in a database)\nlet meVisited = SomeProfile(id: 0, username: "my profile reached from followers list", isMe: true)\nlet bob = SomeProfile(id: 1, username: "Bob", isMe: false)\nlet alex = SomeProfile(id: 2, username: "Alex", isMe: false)\n// example user followers (IRL would be stored in a database)\nlet dict: [Int : [SomeProfile]] = [\n 0 : [bob, alex],\n 1 : [alex, meVisited],\n 2 : [alex, meVisited],\n]\n// example function to get followers of a user (IRL would be a network request)\nfunc getFollowers(for id: Int) -> [SomeProfile] {\n return dict[id]!\n}\nRun Code Online (Sandbox Code Playgroud)\n
您.navigationDestination(...)通过显示包含相同修饰符的视图来重复添加该修饰符。
将所有navigationDestination日志移至关卡中不重复(但不一定)的位置NavigationStack。
像这样:
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)
}
.navigationDestination(for: SomeProfile.self) { profile in
switch profile.isMe {
case true: Text("This is your profile")
case false: SomeProfileView(path: $path, profile: profile)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以.navigationDestination(for: SomeProfile.self)不会一次又一次地被创建。
不要忘记将其从FollowersList
| 归档时间: |
|
| 查看次数: |
2835 次 |
| 最近记录: |