为什么SwiftUI不在工具栏菜单中反映@State属性值?

wkyowqbh  于 2022-09-19  发布在  Swift
关注(0)|答案(2)|浏览(138)

使用Xcode14测试版5测试这段代码。一切正常(使用动画对项目进行排序,并将选定的sortOrder保存在UserDefaults中)。

但是,Menu的标签中的if-else条件似乎被忽略,并且标签不会更新。拜托,你知道为什么吗?或者,有什么替代解决方案可以避免这种情况?

struct ContentView: View {
    enum SortOrder: String, CaseIterable, Identifiable {
        case forward
        case reverse

        var id: Self {
            self
        }

        static let `default`: Self = .forward

        var label: String {
            switch self {
            case .forward: return "Sort (forward)"
            case .reverse: return "Sort (reverse)"
            }
        }
    }

    @AppStorage("sortOrder") var sortOrder: SortOrder = .default {
        didSet {
            sort()
        }
    }

    @State private var items = ["foo", "bar", "baz"]

    @ToolbarContentBuilder
    var toolbar: some ToolbarContent {
        ToolbarItem {
            Menu {
                ForEach(SortOrder.allCases) { sortOrder in
                    Button {
                        withAnimation { self.sortOrder = sortOrder }
                    } label: {
                        // FIXME: doesn't reflect sortOrder value
                        if sortOrder == self.sortOrder {
                            Label(sortOrder.label, systemImage: "checkmark")
                        } else {
                            Text(sortOrder.label)
                        }
                    }
                }
            } label: {
                Label("Actions", systemImage: "ellipsis.circle")
            }
        }
    }

    var body: some View {
        NavigationStack {
            List(items, id: .self) { item in
                Text(item)
            }
            .navigationTitle("Test")
            .toolbar { toolbar }
            .onAppear(perform: sort)
        }
    }

    func sort() {
        switch sortOrder {
        case .forward:
            items.sort(by: <)
        case .reverse:
            items.sort(by: >)
        }
    }
}
vmjh9lq9

vmjh9lq91#

它被选中,但Menu不会更新,假设它在工具栏中应该是持久的。

一种可能的解决方法是在排序更改时强制重新生成菜单,如

Menu {

   // ...

} label: {
    Label("Actions", systemImage: "ellipsis.circle")
}
.id(self.sortOrder)  // << here !!

使用Xcode 14b5/iOS 16进行测试

xzv2uavs

xzv2uavs2#

您的ToolbarItem中的if-else工作正常。这里的问题是工具栏中的.labelStyle默认为.titleOnly

要同时显示带有图标和标题的标签,您需要添加.labelStyle(.titleAndIcon)

相关问题