回答編集履歴

3 s

_Kentarou

_Kentarou score 8289

2018/05/18 08:51  投稿

`UserDefaults`には配列を格納できますので、文字列を保存するより、文字列の配列を保存したほうが扱いやすいです。
Pickerのある画面に戻った時に表示する配列を更新して`Picker`の`reloadAllComponents()`を呼んで下さい。
自分なりに書き直して見ましたので参考にしてください。
```swift
import UIKit
class ListViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
   
   @IBOutlet weak var mainSpinner: UIPickerView! {
       didSet {
           mainSpinner.delegate = self
           mainSpinner.dataSource = self
       }
   }
   var workNames: [String] = []
   
   override func viewDidLoad() {
       super.viewDidLoad()
       
       // 初期値
       // ダミー初期値
       UserDefaults.standard.workNames = ["work1", "work2", "work3"]
   }
   
   override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       
       // 動作確認のためにUserDefaults配列に一つ追加
       var workNames = UserDefaults.standard.workNames
       workNames.append("work")
       UserDefaults.standard.workNames = workNames
   }
   
   override func viewDidAppear(_ animated: Bool) {
       super.viewDidAppear(animated)
       
       // UserDefaultsから配列を取得してPickerをリロード
       workNames = UserDefaults.standard.workNames
       
       if workNames.isEmpty {
           self.performSegue(withIdentifier: "toWorkNameList", sender: nil)
       } else {
           mainSpinner.reloadAllComponents()
       }
   }
   
   func numberOfComponents(in pickerView: UIPickerView) -> Int {
       return 1
   }
   
   func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
       return workNames.count
   }
   
   func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
       return workNames[row]
   }
   
   func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
       print("row: \(row)")
       print("value: \(workNames[row])")
   }
}
// UserDefaultの拡張
extension UserDefaults {
   var workNames: [String] {
       get {
           guard let workNames = UserDefaults.standard.object(forKey: "WorkNames") as? [String] else { return [] }
           return workNames
       }
       set { UserDefaults.standard.set(newValue, forKey: "WorkNames") }
   }
}
```
2 s

_Kentarou

_Kentarou score 8289

2018/05/18 08:50  投稿

`UserDefaults`には配列を格納できますので、文字列を保存するより、文字列の配列を保存したほうが扱いやすいです。
Pickerのある画面に戻った時に表示する配列を更新して`Picker`の`reloadAllComponents()`を呼んで下さい。
自分なりに書き直して見ましたので参考にしてください。
```swift
import UIKit
class ListViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
   
   @IBOutlet weak var mainSpinner: UIPickerView! {
       didSet {
           mainSpinner.delegate = self
           mainSpinner.dataSource = self
       }
   }
   var workNames: [String] = []
   
   override func viewDidLoad() {
       super.viewDidLoad()
       
       // ダミーの初期値
       // 初期値
       UserDefaults.standard.workNames = ["work1", "work2", "work3"]
   }
   
   override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       
       // 動作確認のために次の画面から戻った時にUserDefaults配列に一つ追加
       // 動作確認のためにUserDefaults配列に一つ追加
       var workNames = UserDefaults.standard.workNames
       workNames.append("work")
       UserDefaults.standard.workNames = workNames
   }
   
   override func viewDidAppear(_ animated: Bool) {
       super.viewDidAppear(animated)
       
       // UserDefaultsから配列を取得してPickerをリロード
       workNames = UserDefaults.standard.workNames
       mainSpinner.reloadAllComponents()
       
       if workNames.isEmpty {
           self.performSegue(withIdentifier: "toWorkNameList", sender: nil)
       } else {
           mainSpinner.reloadAllComponents()
       }
   }
   
   func numberOfComponents(in pickerView: UIPickerView) -> Int {
       return 1
   }
   
   func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
       return workNames.count
   }
   
   func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
       return workNames[row]
   }
   
   func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
       print("row: \(row)")
       print("value: \(workNames[row])")
   }
}
// UserDefaultの拡張
extension UserDefaults {
   var workNames: [String] {
       get {
           guard let workNames = UserDefaults.standard.object(forKey: "WorkNames") as? [String] else { return [] }
           return workNames
       }
       set { UserDefaults.standard.set(newValue, forKey: "WorkNames") }
   }
}
 
 
```
1 修正

_Kentarou

_Kentarou score 8289

2018/05/18 08:47  投稿

Pickerのある画面に戻った時に表示する配列を更新して`Picker`の`reloadAllComponents()`をんで下さい。
Pickerのある画面に戻った時に表示する配列を更新して`Picker`の`reloadAllComponents()`をんで下さい。
自分なりに書き直して見ましたので参考にしてください。
```swift
import UIKit
class ListViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
   
   @IBOutlet weak var mainSpinner: UIPickerView! {
       didSet {
           mainSpinner.delegate = self
           mainSpinner.dataSource = self
       }
   }
   var workNames: [String] = []
   
   override func viewDidLoad() {
       super.viewDidLoad()
       
       // ダミーの初期値
       UserDefaults.standard.workNames = ["work1", "work2", "work3"]
   }
   
   override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       
       // 動作確認のために次の画面から戻った時にUserDefaults配列に一つ追加
       var workNames = UserDefaults.standard.workNames
       workNames.append("work")
       UserDefaults.standard.workNames = workNames
   }
   
   override func viewDidAppear(_ animated: Bool) {
       super.viewDidAppear(animated)
       
       // UserDefaultsから配列を取得してPickerをリロード
       workNames = UserDefaults.standard.workNames
       mainSpinner.reloadAllComponents()
   }
   
   func numberOfComponents(in pickerView: UIPickerView) -> Int {
       return 1
   }
   
   func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
       return workNames.count
   }
   
   func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
       return workNames[row]
   }
   
   func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
       print("row: \(row)")
       print("value: \(workNames[row])")
   }
}
// UserDefaultの拡張
extension UserDefaults {
   var workNames: [String] {
       get {
           guard let workNames = UserDefaults.standard.object(forKey: "WorkNames") as? [String] else { return [] }
           return workNames
       }
       set { UserDefaults.standard.set(newValue, forKey: "WorkNames") }
   }
}
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る