【问题标题】:SwiftUI TabView index view not respecting page view indexSwiftUI TabView 索引视图不尊重页面视图索引
【发布时间】:2021-03-19 18:17:31
【问题描述】:

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

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

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

发生的情况是索引根本没有更新。在原始代码中,它实际上滞后 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


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢!我最初的想法是不是因为我没有在视图本身中使用 @Binding 属性包装器而行不通?如果是这样,那会是更传统的方式吗?
    • 刚刚尝试从 _selectedItem 中删除 @Published 包装器并将绑定注入到视图中的 @Binding var 中,指示器现在执行“滞后一个”的操作。
    • @elight 我真的不知道你对@Binding 的最初想法是什么。但是@Published 解决方案在这里应该没问题。如果您还有其他问题,请创建一个新帖子,我会尽力为您提供帮助。
    猜你喜欢
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多