#ios #arrays #swift #nsuserdefaults #userdefaults
#iOS #массивы #swift #nsuserdefaults #ошибки пользователя
Вопрос:
Я использую переход для перехода от контроллера представления 1 к контроллеру представления 2. Контроллер представления 1 имеет кнопку, которая устанавливает постоянные данные при нажатии на нее:
Я объявляю глобальную переменную для пользователя по умолчанию:
let userDefault = UserDefaults()
Вот моя кнопка для установки пользователем по умолчанию строки с текстовыми значениями из меток:
@IBAction func saving(_ sender: UIButton) {
let savedText = "Gallon (gallonTextFieldOutlet.text) is equal to Litre (litreTextFieldOutlet.text) is equal to Pint (pintTextFieldOutlet.text)"
userDefault.setValue(savedText, forKey: "SavedConversion")
}
Затем я получаю ссылку на View Controller 2 и передаю это значение пользователя по умолчанию, когда пользователь переходит от View Controller 1 к View Controller 2 через переход:
// in view controller 2: reference to get persistent data
var volumeDataOne:String?
// in view controller 2: instantiation of my queue class to use methods
var queue = Queue<String>()
// segue action in view controller 1
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "savedVolumeData"
{
let historyVC:VolumeHistoryViewController = segue.destination as! VolumeHistoryViewController
if let value = userDefault.value(forKey: "SavedConversion") as? String {
historyVC.volumeDataOne = value
}
}
Я получаю это в контроллере представления 2 и пытаюсь установить для этого три метки, которые у меня есть в этом контроллере представления:
func DisplayVolumeHistory() {
let labelArray = [volumeDataLabelOutlet, volumeDataLabelTwoOutlet, volumeDataLabelThreeOutlet]
if let bindingOptional = volumeDataOne
{
for index in 0..<labelArray.count
{
queue.enqueue(val: bindingOptional)
labelArray[index]?.text = queue.arr[index]
}
}
}
В моей спецификации мне сказали, что данные должны быть постоянными и что одновременно могут храниться только последние пять данных. Итак, у меня есть класс, который я назвал Queue, на который ссылается эта функция. Эта функция вызывается в viewDidLoad контроллера представления 2.
override func viewDidLoad() {
super.viewDidLoad()
//Debug ...
volumeDataLabelOutlet.text = "na"
volumeDataLabelTwoOutlet.text = "na 2"
volumeDataLabelThreeOutlet.text = "na 3"
//...
DisplayVolumeHistory()
// Do any additional setup after loading the view.
}
Я протестировал свой класс очереди на игровой площадке, и он работает так, как ожидалось. Класс очереди можно увидеть здесь:
очередь классов {
var arr = [T]()
func enqueue(val: T){
if(arr.count < 3) {
arr.append(val)
} else {
for i in 0..<arr.count-1 {
arr[i] = arr[i 1]
}
arr[arr.count - 1] = val
}
}
func dequeue() -> (T?){
if (arr.isEmpty){
return nil
} else {
return arr.remove(at: 0)
}
}
}
Вот моя проблема, которую я, похоже, не могу понять. В контроллере представления 2 все три метки будут содержать постоянные данные, но все они будут содержать одни и те же данные,
Например, если у меня есть следующие данные:
DATA 1: 555
DATA 2: 700
DATA 3: 62
Я бы хотел:
LABEL 1 --> 555
LABEL 2 --> 700
LABEL 3 --> 62
Однако в настоящее время это будет:
LABEL 1 --> 62
LABEL 2 --> 62
LABEL 3 --> 62
Я не уверен, почему отладка. Я полагаю, это связано с тем, что мои постоянные данные в моем контроллере представления 1 принимают только строку, которую словарь переопределяет, поскольку я использую тот же ключ.
Однако я просмотрел документацию и попытался использовать пользовательский массив по умолчанию, который не решил мою проблему, и я не уверен, что вызывает эту проблему.
Я ценю любые рекомендации и помощь в попытке решить эту проблему.
Спасибо
Ответ №1:
Вы правы в своем комментарии,
который словарь переопределяет, поскольку я использую тот же ключ
Каждый раз, когда вы нажимаете эту кнопку, вы переопределяете значение новым. Таким образом, вы должны всегда видеть на своем v2, последнем.
Поэтому, вероятно, вам следует хранить массив вместо строки.
//on v1
var values = [String]()
@IBAction func saving(_ sender: UIButton) {
let savedText = "Gallon (gallonTextFieldOutlet.text) is equal to Litre (litreTextFieldOutlet.text) is equal to Pint (pintTextFieldOutlet.text)"
values.append(savedText)
UserDefaults.standard.setValue(values, forKey: "SavedConversion")
}
Вы передадите его в v2, как и сейчас
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "savedVolumeData"
{
let historyVC:VolumeHistoryViewController = segue.destination as! VolumeHistoryViewController
if let values = userDefault.value(forKey: "SavedConversion") as? [String] {
historyVC.volumeDataOne = values //volumeDataOne now needs to be an [String]
}
}
Затем в версии V2 просмотрите свой массив и метки.
Комментарии:
1. Привет. Спасибо за ответ. Приятно знать, что я был на правильном пути с моими ограниченными знаниями о Swift. Я реализовал его, и теперь у меня проблема, когда обновляется только одна метка, поэтому теперь я считаю, что я неправильно перебираю свои массивы и изучаю это. Я также вижу, как кто-то еще говорит, что uitextfield проще использовать для чего-то подобного, чем метки на другом форуме, поэтому я тоже изучаю это. В целом я хотел бы поблагодарить вас за быстрый и подробный ответ. 🙂
2. @StackSqueegee нет проблем, надеюсь, это поможет.