ios - 如何从自定义单元格保存 UILabel 以便每次打开应用程序时它都会显示最新更改?

标签 ios swift iphone uitableview nsuserdefaults

我是 Swift 的初学者。我已经用尽了所有的尝试和错误,需要帮助!!

我正在使用 UITableView 和包含 UILabel 和 UIButton 的自定义单元格创建记分板项目。按下按钮后,UILabel 会递增 1 以模拟玩家的点。我在保存 UILabel 中的点时遇到问题,因此每次我打开应用程序时,该玩家的点都会保留。我尝试过使用 UserDefaults、结构和委托(delegate),但没有任何运气......我可能做错了。我只需要知道正确的方法是什么。

注意:我能够从 UIAlertController 成功保存玩家名称,这样当我打开应用程序时,名称仍然存在,除非我删除它们,但没有运气保存每个名称本身的积分,它们仍然保持“0”。

当我关闭然后打开应用程序时,它应该看起来像这样,但只有在打开应用程序时才会这样做:

Scoreboard UITableView - Screenshot

这是 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 协议(protocol),通过在您自己的类型上采用 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)
        }
    }
}

关于ios - 如何从自定义单元格保存 UILabel 以便每次打开应用程序时它都会显示最新更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54504805/

相关文章:

ios - 从 CollectionViewCell 中的 UIButton 打开 URL

ios - 静态表格 View 中的单元格内容未显示

iphone - iPhone UI 自定义的最佳方法是什么?

ios - 将数据传递到表格单元格

ios - 如何在 Swift 中同步对我的 web 服务的调用并在 map 上显示数据(使用标记聚类)?

ios - IOS中如何读取应用程序的证书信息

iphone - iPhone 应用程序可以充当服务器来发送消息或推送通知吗?

ios - Xcode 4.6-整数本身乘以四吗?

ios - 使用 Cocoapods v1.0.x 拉取 pod 时未构建 MagicalRecord

xcode - 在不使用 SpriteKit 中的便捷初始化程序的情况下初始化 Circle Sprite 节点