使用UserDefaults更新数据模型

时间:2018-06-20 19:39:01

标签: swift uicollectionview nsuserdefaults uicollectionviewcell

我正在使用“收藏夹视图”显示大约30个不同的单元格。每个单元格代表一项冬季运动。这些单元格由静态数据模型填充,并且在每次App更新时更新(没有数据库)。

由于我总是添加到运动列表中,所以我想在添加的最新运动上显示“ NEW”徽章。当用户点击该特定运动时,“ NEW”标志消失,并通过UserDefaults保留。屏幕显示如下:

stateChanged

我的进度如下。我只是坚持保留“新”属性,因此一旦点击“新”运动,布尔值将变为false并在UserDefaults中更新。

模型。。在这里我将更新新标志。如果正确,它将显示徽章(最终将取消隐藏图像视图。

struct WinterModel {
    let sportName: String
    var new: Bool
}

struct WinterData {
    static func allSports() -> [WinterModel] {
        return [
            WinterModel(sportName: "Luge", new: true),
            WinterModel(sportName: "Curling", new: false),
            WinterModel(sportName: "Skeleton", new: false),
            WinterModel(sportName: "Speed Skating", new: false),
            WinterModel(sportName: "Bobsleigh", new: false)
            // 30+ more
        ]
    }
}

主VC。填充集合视图。

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    var winter = WinterData.allSports()

    @IBOutlet weak var sportCollectionView: UICollectionView!

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return winter.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ID", for: indexPath as IndexPath) as! WinterSportCell
        let sport = winter[indexPath.item]
        cell.sport = sport
        return cell
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        sportCollectionView.dataSource = self
        sportCollectionView.delegate = self
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // Cell was changed... Change data model to false?
    }

}

最后, UICollectionViewCell

class WinterSportCell: UICollectionViewCell { 
    @IBOutlet weak var sportNameLabel: UILabel!
    @IBOutlet weak var newOutlet: UILabel!
    var sport: WinterModel! {
        didSet {
            self.updateUI()
        }
    }
    func updateUI() {
        sportNameLabel.text = sport.sportName
        if sport.new {
            newOutlet.isHidden = false
        } else {
            newOutlet.isHidden = true
        }
    }
}

如何配置UserDefaults,以便在用户点击该单元格时将数据模型的'new'属性更新为false?

1 个答案:

答案 0 :(得分:2)

您可以添加属性ID或检查winterModel.name以更新新属性。您需要使用可编码将模型保存到UserDefault。

struct WinterModel: Codable {
    var id: Int
    let sportName: String
    var new: Bool
}

struct WinterDefaults {

    private static let winterDefaults = UserDefaults.standard
    private static let key = "Winter"
    private static let decoder = JSONDecoder()
    private static let encoder = JSONEncoder()
    private init() {}

    static func getWinterModels() -> [WinterModel]? {

        var winterModel: [WinterModel]?
        if let data = UserDefaults.standard.value(forKey: key) as? Data {
            winterModel = try? decoder.decode([WinterModel].self, from: data)
        }

        return winterModel
    }

    static func saveWinterModels(with winter: [WinterModel]) {
        let data = try? encoder.encode(winter)
        winterDefaults.set(data, forKey: key)
    }

    static func updateWinterModels(with winter: WinterModel) {

        var winterModels = getWinterModels()

        if winterModels != nil {

            for i in 0..<winterModels!.count {
                if winterModels?[i].id == winter.id {
                    winterModels?[i].new = false
                }
            }

            saveWinterModels(with: winterModels!)
        }
    }

}

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    @IBOutlet weak var sportCollectionView: UICollectionView!

    var winterList: [WinterModel]?

    override func viewDidLoad() {
        super.viewDidLoad()

        sportCollectionView.dataSource = self
        sportCollectionView.delegate = self

        if let winters = WinterDefaults.getWinterModels() {
            winterList = winters
        } else {
            let winters = getWinterList()
            winterList = winters
            WinterDefaults.saveWinterModels(with: winters)
        }

    }

    func getWinterList() -> [WinterModel] {
        return [
            WinterModel(id: 0, sportName: "Luge", new: true),
            WinterModel(id: 1, sportName: "Curling", new: false),
            WinterModel(id: 2, sportName: "Skeleton", new: false),
            WinterModel(id: 3, sportName: "Speed Skating", new: false),
            WinterModel(id: 4, sportName: "Bobsleigh", new: false)
        ]
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return winterList?.count ?? 0
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ID", for: indexPath as IndexPath) as? WinterSportCell else {
            return UICollectionViewCell()
        }

        if let winter = winterList?[indexPath.row] {
            cell.sport = winter
        }

        return cell

    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if winterList != nil {
            winterList![indexPath.row].new = false
            sportCollectionView.reloadData()
            WinterDefaults.saveWinterModels(with: winterList!)
        }
    }

}

class WinterSportCell: UICollectionViewCell {
    @IBOutlet weak var sportNameLabel: UILabel!
    @IBOutlet weak var newOutlet: UILabel!
    var sport: WinterModel! {
        didSet {
            sportNameLabel.text = sport.sportName
            newOutlet.isHidden = sport.new
        }
    }
}