1


I'm using SwiftUI to create a TabView for macOS.
I hope,
1)when user clicks a tabItem will save the selected tab number to UserDefaults(using my @propertyWrapper @UserDefault).
2)When this application restart will auto select the tabItem by selected tab number in UserDefaults.

Problem: Does not have any effect when I click a tabItem.
Could give me some advice or correct way to do this?
thanks

enter image description here

My @propertyWrapper

@propertyWrapper
struct UserDefault<T> {
    let key: String
    let value: T

    init(key: String, value: T) {
        self.key = key
        self.value = value
    }

    var wrappedValue: T {
        get {
            return UserDefaults.standard.value(forKey: self.key) as? T ?? self.value
        }
        set {
            UserDefaults.standard.set(newValue, forKey: self.key)
        }
    }
}

struct UserDefaultsConfig {
    @UserDefault(key: "SelectedTab", value: 0) static var selectedTab: Int
}

SwiftUI View

struct ContentView: View {
    @State var selectedTab = UserDefaultsConfig.selectedTab
    var body: some View {
        TabView(selection: self.$selectedTab) {
            Text("Tab0 Content")
                .tabItem {
                    Text("Tab0")
                }.tag(0)

           Text("Tab1 Content")
                .tabItem {
                    Text("Tab1")
                }.tag(1)

            Text("Tab2 Content")
                .tabItem {
                    Text("Tab2")
                }.tag(2)

            Text("Tab3 Content")
                .tabItem {
                    Text("Tab3")
                }.tag(3)
        }
    }
}
CocoaUser
  • 1,361
  • 1
  • 15
  • 30
  • Your question how to use user defaults with SwiftUI is already covered here https://stackoverflow.com/questions/56822195/how-do-i-use-userdefaults-with-swiftui/57029469#57029469 – Marc T. Dec 12 '19 at 07:08

1 Answers1

0

This

@State var selectedTab = UserDefaultsConfig.selectedTab

only provides initial value for selectedTab read from UserDefaults, but never save it back.

Theoretically you would need to apply @UserDefault(key: "SelectedTab", value: 0) directly to var selectedTab, but multiple property wrappers are not supported now.

The following gives the behaviour which you expect

struct ContentView: View {

    var body: some View {
        TabView(selection: Binding<Int>(
            get: { UserDefaultsConfig.selectedTab },
            set: { UserDefaultsConfig.selectedTab = $0 }
        )) {
            Text("Tab0 Content")
                .tabItem {
                    Text("Tab0")
                }
                .tag(0)
            ...
damirstuhec
  • 6,069
  • 1
  • 22
  • 39
Asperi
  • 228,894
  • 20
  • 464
  • 690