如何从另一个ViewController检索UseDefault保存的数据

时间:2019-06-17 18:43:22

标签: ios swift

我有2个ViewController,一个显示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上设置两个标签?

2 个答案:

答案 0 :(得分:2)

定义模型以表示要存储和还原的数据:

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根本不是个好主意。如果要从代码中的任何位置访问某些数据,则应遵循 singleton模式,并定义自己的单例实例,而不是标准的userdefault。

答案 1 :(得分:0)

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

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]