new*_*our 3 swift swiftui swiftui-navigationview
我的第一个屏幕上有一个ListID 和分数。
在详细信息屏幕中,我单击并调用一个回调,该回调会添加到分数并按List分数进行排序。
当我对列表顶部的项目执行此操作时,没有任何反应。(好的)
当我对列表底部的项目执行此操作时,导航视图会弹出后退堆栈并将我带回到第一页。(坏的)
import SwiftUI
class IdAndScoreItem {
var id: Int
var score: Int
init(id: Int, score: Int) {
self.id = id
self.score = score
}
}
@main
struct CrazyBackStackProblemApp: App {
var body: some Scene {
WindowGroup {
NavigationView {
ListView()
}
.navigationViewStyle(.stack)
}
}
}
struct ListView: View {
@State var items = (1...50).map { IdAndScoreItem(id: $0, score: 0) }
func addScoreAndSort(item: IdAndScoreItem) {
items = items
.map {
if($0.id == item.id) { $0.score += 1 }
return $0
}
.sorted {
$0.score > $1.score
}
}
var body: some View {
List(items, id: \.id) { item in
NavigationLink {
ScoreClickerView(
onClick: { addScoreAndSort(item: item) }
)
} label: {
Text("id: \(item.id) score:\(item.score)")
}
}
}
}
struct ScoreClickerView: View {
var onClick: () -> Void
var body: some View {
Text("tap me to increase the score")
.onTapGesture {
onClick()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点,以便我在详细信息页面上对列表进行重新排序,这会反映在列表页面上,但导航堆栈不会弹出(当我在列表底部的列表项上执行此操作时)。我尝试添加navigationStyle(.stack)了没有效果。
感谢您的任何帮助!
Resort 更改了 ID 的顺序,使列表重新创建内容,导致当前的 NavigationLink 被破坏,因此导航回来。
一种可能的解决方案是将链接与内容分开 - 可以通过引入诸如选择(点击的行)之类的内容以及通过该选择激活的导航链接来完成。
使用 Xcode 14 / iOS 16 进行测试
@State private var selectedItem: IdAndScoreItem? // selection !!
var isNavigate: Binding<Bool> { // link activator !!
Binding(get: { selectedItem != nil}, set: { _ in selectedItem = nil })
}
var body: some View {
List(items, id: \.id) { item in
Text("id: \(item.id) score:\(item.score)") // tappable row
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(Rectangle())
.onTapGesture {
selectedItem = item
}
}
.background(
NavigationLink(isActive: isNavigate) { // one link !!
ScoreClickerView {
if let item = selectedItem {
addScoreAndSort(item: item)
}
}
} label: {
EmptyView()
}
)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
403 次 |
| 最近记录: |