Как сохранить UILabel из пользовательской ячейки, чтобы при каждом открытии приложения отображались последние изменения? - PullRequest
0 голосов
/ 03 февраля 2019

Я новичок в Swift.Я исчерпал все свои пробные версии и ошибки и мне нужна помощь !!

Я создаю проект табло, используя UITableView с пользовательской ячейкой, которая содержит UILabel и UIButton.После нажатия кнопки UILabel увеличивается на единицу, чтобы смоделировать точку для игрока.У меня возникают проблемы с сохранением точки в UILabel, чтобы при каждом открытии приложения осталась точка для этого игрока.Я пытался использовать UserDefaults, структуры и делегаты, но мне не повезло ... Я могу сделать это неправильно.Мне просто нужно знать, каков правильный подход для этого.

Примечание: я могу успешно сохранить имя игрока из UIAlertController, чтобы при открытии приложения имена оставались там, пока я их не удалю,но не удалось сохранить очки для каждого имени, они по-прежнему остаются «0».

Это должно выглядеть так, когда я закрываю и открываю приложение, но это происходит только тогда, когда приложениеоткрыто:

Табло UITableView - Снимок экрана

Вот код ViewController:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var items = [String]()

    @IBOutlet weak var listTableView: UITableView!
    @IBAction func addItem(_ sender: AnyObject) {
        alert()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        listTableView.dataSource = self
        self.items = UserDefaults.standard.stringArray(forKey:"items")  ?? [String]()
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PointsCell

        cell.textLabel?.text = items[indexPath.row]

        return cell
    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    func saveData() {
        UserDefaults.standard.set(items, forKey: "items")
    }

    func alert(){
        let alert = UIAlertController(title: "Add Player", message: "", preferredStyle: .alert)
        alert.addTextField{
            (textfield) in
            textfield.placeholder = " Enter Player Name "

        }
        let add = UIAlertAction(title: "Add", style: .default)
            {

            (action) in guard let textfield = alert.textFields?.first else {return}

            if let newText = textfield.text
            {
                self.items.append(newText)
                self.saveData()
                let indexPath = IndexPath(row: self.items.count - 1, section: 0)
                self.listTableView.insertRows(at: [indexPath], with: .automatic)
            }
        }

        let cancel = UIAlertAction(title: "Cancel", style: .cancel) {
            (alert) in

        }

        alert.addAction(add)
        alert.addAction(cancel)

        present(alert, animated: true, completion: nil)

    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        items.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .automatic)
        saveData()

    }

}

Вот мой пользовательский код ячейки PointsCell:

import UIKit

class PointsCell: UITableViewCell {

    var winScore = 0
    @IBOutlet weak var scoreUILabel: UILabel!

   @IBAction func pointButtonPressed(_ sender: Any) {
        winScore += 1
        scoreUILabel.text = "\(winScore)"

    }

}

1 Ответ

0 голосов
/ 05 февраля 2019

Очки по-прежнему остаются 0, потому что вы сохраняете их, во-первых, вам нужны очки для каждого игрока, поэтому вам нужно объединить имя игрока и счет в объект.

class Player:NSObject, Codable{
    let name: String
    var score : Int
    init(name: String, score: Int) {
        self.name = name
        self.score = score
    }
    override var description: String{
        return "Name :" + self.name + " Score :" + String(self.score )
    }
}

Swift 4 представил протокол Codable,Принятие Codable для ваших собственных типов позволяет вам сериализовать их в любой из встроенных форматов данных и из них.

Теперь вы можете легко получить доступ к плееру с именем и счетом.

var players = [Player]()

Чтобы получить сохраненное значение из UserDefaults

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if let items: Data = UserDefaults.standard.object(forKey: "items") as? Data{
            self.players = try! PropertyListDecoder().decode([Player].self, from: items)
            self.listTableView.reloadData()
        }
    }

Когда вы добавляете нового игрока в свой список, создайте новый экземпляр Player и добавьте его в список.

func alert(){
    let alert = UIAlertController(title: "Add Player", message: "", preferredStyle: .alert)
    alert.addTextField{
        (textfield) in
        textfield.placeholder = " Enter Player Name "

    }
    let add = UIAlertAction(title: "Add", style: .default)
    {
        (action) in guard let textfield = alert.textFields?.first else {return}
        if let newText = textfield.text
        {
            let player = Player(name: newText, score: 0)
            self.players.append(player)
            let indexPath = IndexPath(row: self.players.count - 1, section: 0)
            self.listTableView.insertRows(at: [indexPath], with: .automatic)
        }
    }

    let cancel = UIAlertAction(title: "Cancel", style: .cancel) {
        (alert) in

    }
    alert.addAction(add)
    alert.addAction(cancel)
    present(alert, animated: true, completion: nil)

}

Теперь обновитеВаш метод UITableViewDataSource как новый элемент списка.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PointsCell
    cell.player = players[indexPath.row]
    return cell
}

теперь необходимо обновить метод saveData для сохранения нового списка в UserDefaults, этот метод вызывается всякий раз, когда вы хотите сохранить свой список.

func saveData() {
    UserDefaults.standard.set(try! PropertyListEncoder().encode(self.players), forKey: "items")
}

PointsCell класс также необходимо обновить как новый тип объекта:

class PointsCell: UITableViewCell {
    @IBOutlet weak var scoreUILabel: UILabel!
    @IBOutlet weak var nameUILabel: UILabel!

    var player: Player? {
        didSet{
            if let name = player?.name {
                self.nameUILabel?.text = name
            }
            if let score = player?.score {
                self.scoreUILabel?.text = String(score)
            }
        }
    }

    @IBAction func pointbuttonPressed(_ sender: Any) {
        if self.player != nil{
            let score = self.player?.score ?? 0
            self.player?.score = score + 1
            scoreUILabel.text = String(self.player?.score ?? 0)
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...