首页 > 解决方案 > SwiftUI TabView 索引视图不尊重页面视图索引

问题描述

我的目标是将当前 TabView 索引的真实来源保持在应用程序状态内。但我没有看到 SwiftUI TabView 索引指示器的预期行为。

我能做的是获得以下两种结果之一:让绑定正确更新事实来源,或者让指标按预期工作。我似乎不能两者兼得。

我已经将我的代码剥离到下面的测试用例中。我希望 TabView 索引视图(指示器)更新并显示当前视图在 TabView 内容数组中的索引位置(当然,相对而言,所以 + 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)
        }
    }
}

标签: swiftui

解决方案


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

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

推荐阅读