如何从另一个视图控制器检索 UseDefault 保存的数据



我有 2 个视图控制器,一个显示 UI,第二个显示用作设置按钮的分段控件。 我使用以下代码保存分段控件状态:

UserDefaults.standard.set(selectorLabel.selectedSegmentIndex, forKey: "stateSelected")  

然后,我在 viewdidload 方法上检索该 usedefault:

if let value = UserDefaults.standard.value(forKey: "stateSelected"){  
            let selectedIndex = value as! Int  
            selectorLabel.selectedSegmentIndex = selectedIndex  
        } 

到目前为止,这按预期工作,并且每次加载应用时都会正确加载分段受控的状态。

分段控件有两个文本标题 - 一个是"LBs & INs",第二个是"KGs & CMs"。

如何将这两个分段控件文本标题另存为 UserDefaults,然后在第一个 ViewController 上调用它们以在 viewdidload 上设置两个标签?

定义一个模型来表示要存储和恢复的数据:

struct SegmentedControlState: Codable {
    let selectedIndex: Int
    let titles: [String]
}

初始化模型,编码并将其存储在某个地方(如用户默认值(:

func saveState(of segmentedControl: UISegmentedControl) {
    let state = SegmentedControlState(
        selectedIndex: segmentedControl.selectedSegmentIndex,
        titles: (0..<segmentedControl.numberOfSegments).map { segmentedControl.titleForSegment(at: $0) ?? ""})
    let plist = try! PropertyListEncoder().encode(state)
    UserDefaults.standard.set(plist, forKey: "SegmentedControlState")
    //UserDefaults.standard.synchronize() //if targeting older iOS
}

要恢复,您应该像这样颠倒顺序:

func loadState(on segmentedControl: UISegmentedControl) {
    guard let plist = UserDefaults.standard.value(forKey: "SegmentedControlState") as? Data else { return }
    let state = try! PropertyListDecoder().decode(SegmentedControlState.self, from: plist)
    for element in state.titles.enumerated() {
        segmentedControl.setTitle(element.element, forSegmentAt: element.offset)
    }
    segmentedControl.selectedSegmentIndex = state.selectedIndex
}

用法:

// store `selectorLabel` data
saveState(of: selectorLabel)
// restore `selectorLabel` data
loadState(on: selectorLabel)

请注意,将这样的数据存储到userdefaults根本不是一个好主意。如果要从代码中的任何位置访问某些数据,则应遵循单一实例模式并定义自己的单一实例,而不是标准 userdefault。

只需将值存储为字符串,而不是整数索引。

UserDefaults.standard.set(selectorLabel.titleForSegment(at: selectorLabel.selectedSegmentIndex), forKey: "stateSelected")

然后检索:

UserDefaults.standard.string(forKey: "stateSelected")

编辑:上面@rmaddy是正确的 - 理想情况下,您应该像您已经做的那样存储索引值,然后使用数组来确定索引引用的标题(比仅使用标题作为参考更干净(。您可以将此阵列设置为全局,以便在必要时可以从任何位置进行访问。

segmentedControlTitles: [String] = ["LBs & INs", "KGs & CMs"]

然后打电话过来

let index = UserDefaults.standard.integer(forKey: "stateSelected")
let title = segmentedControlTitles[index]

最新更新