SwiftUI选项卡视图索引视图不考虑页面视图索引

SwiftUI选项卡视图索引视图不考虑页面视图索引,swiftui,Swiftui,我的目标是将当前TabView索引的真实来源保持在appstate中。但我并没有看到我期望从SwiftUI TabView索引指示器中看到的行为 我能做的是有两种结果中的一种:让绑定正确地更新真相的来源,或者让指标按预期工作。我似乎不能两者兼得 我已经将代码精简到下面的测试用例中。我希望TabView索引视图(指示器)更新并显示当前视图在TabView内容数组中的索引位置(当然相对而言,so+1) 结果是索引根本不更新。在原始代码中,它实际上滞后了一个 有经验的人能提供一些建议或指出我的错误吗

我的目标是将当前TabView索引的真实来源保持在appstate中。但我并没有看到我期望从SwiftUI TabView索引指示器中看到的行为

我能做的是有两种结果中的一种:让绑定正确地更新真相的来源,或者让指标按预期工作。我似乎不能两者兼得

我已经将代码精简到下面的测试用例中。我希望TabView索引视图(指示器)更新并显示当前视图在TabView内容数组中的索引位置(当然相对而言,so+1)

结果是索引根本不更新。在原始代码中,它实际上滞后了一个

有经验的人能提供一些建议或指出我的错误吗

import SwiftUI

class Item: Identifiable {
    let id = Int.random(in: 0..<1000)
}

class SourceOfTruth: ObservableObject {
    @Published var items: [Item] = [Item(), Item(), Item()]
    /// Source of truth for app state
    var _selectedItem: Int? {
        willSet {
            print("\(newValue ?? 0)")
        }
    }
    /// Exposed SwiftUI binding
    public lazy var selectedItem: Binding<Int> = Binding<Int>(get: {
        self._selectedItem ?? -1
    }, set: {
        self._selectedItem = $0
    })

    init () {
        _selectedItem = items.first?.id
    }
}

struct BindingTestView: View {
    @EnvironmentObject var appState: SourceOfTruth

    var body: some View {
        if appState.items.count > 0 {
            TabView(selection: appState.selectedItem) {
                ForEach(appState.items) { item in
                    Text("\(item.id)")
                            .tag(item.id)
                }
            }
                    .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
                    .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
        } else {
            Text("No items")
        }
    }
}

@main
struct SwiftUICombineTestingApp: App {
    let appState = SourceOfTruth()

    var body: some Scene {
        WindowGroup {
            BindingTestView().environmentObject(appState)
        }
    }
}
导入快捷界面
类别项目:可识别{
设id=Int.random(in:0..0{
选项卡视图(选择:appState.selectedItem){
ForEach(appState.items){item在
文本(“\(item.id)”)
.tag(item.id)
}
}
.tabViewStyle(页面tabViewStyle(indexDisplayMode:.始终))
.indexViewStyle(PageIndexViewStyle(背景显示模式:。始终))
}否则{
文本(“无项目”)
}
}
}
@主要
结构SwiftUICombineTestingApp:App{
让appState=SourceOfTruth()
var body:一些场景{
窗口组{
BindingTestView().environmentObject(appState)
}
}
}

您需要添加
@Published
,以便视图可以观察变量:

@Published var _selectedItem: Int? {
    willSet {
        print("\(newValue ?? 0)")
    }
}

谢谢!我最初的想法不起作用是因为我没有在视图中使用
@Binding
属性包装器吗?如果是这样,那会是更传统的方式吗?根据我最后的评论,不是注入
@EnvironmentObject appState
和使用class对象,而是在视图中使用
@Binding var
,然后通过应用注入tate at view init?刚刚尝试从
\u selectedItem
中删除
@Published
包装,并将绑定注入视图中的
@Binding var
,指示器现在执行“滞后一个”操作。@Ellight我真的不知道你最初对
@Binding
的想法是什么。但是
@Published
的解决方案在这里应该是好的。如果你还有更多的问题,请创建一个新的职位,我会尽力帮助你。