簡體   English   中英

如何從自定義單元格保存UILabel,以便每次我打開應用程序時都顯示最新更改?

[英]How to save UILabel from custom cell so that every time I open the app it displays the latest change?

我是Swift的初學者。 我已經用盡了所有的嘗試和錯誤,需要幫助!

我正在使用帶有自定義單元格的UITableView創建記分板項目,該自定義單元格包含UILabel和UIButton。 按下按鈕后,UILabel會增加1,以為播放器模擬一個點。 我在將積分保存到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)"

    }

}

分數仍然保持為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添加到列表時,請創建新的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)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM