【问题标题】:Using UserDefaults on an UITableView在 UITableView 上使用 UserDefaults
【发布时间】:2017-05-22 23:51:20
【问题描述】:

我正在制作一个使用 Blogger API 的应用。在第一个选项卡中,我可以搜索帖子并显示其内容。此外,我可以将帖子添加到第二个选项卡的“收藏夹”部分。一切正常,直到我关闭应用程序。重新启动后,收藏夹部分消失了。我尝试实现 UserDefaults,以便在杀死应用程序后收藏夹部分不会变空,但它不起作用。

这是将帖子添加到收藏夹的按钮的代码:

vc.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTapped))

func addTapped() {
    offlineTitles.append(cellText)
    titlesArray.append(cellText)
    subtitlesArray.append(cellSubtitle)
    let defaults = UserDefaults.standard
    defaults.set(titlesArray, forKey: "title")
    defaults.set(subtitlesArray, forKey: "subtitle")
    NotificationCenter.default.post(name: .reload, object: nil)
    let ac = UIAlertController(title: "Added!", message: "Post added to favorites", preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "Great!", style: .default))
    present(ac, animated: true)
}

这适用于 FavoritesViewController.swift :

import UIKit

var offlineTitles = [String]()
var titlesArray = [String]()
var subtitlesArray = [String]()


extension Notification.Name {
static let reload = Notification.Name("reload")
}

class OfflineViewController: UITableViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(reloadTableData(_:)), name: .reload, object: nil)
    self.tableView.allowsMultipleSelectionDuringEditing = false
}

func reloadTableData(_ notification: Notification) {
    self.tableView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return titlesArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "OfflineCell", for: indexPath)
    let defaults = UserDefaults.standard
    let userDefaultsTitleArray = defaults.array(forKey: "title") as? [String] ?? [String]()
    let userDefaultsSubtitleArray = defaults.array(forKey: "subtitle") as? [String] ?? [String]()
    let title = userDefaultsTitleArray[indexPath.row]
    let subtitle = userDefaultsSubtitleArray[indexPath.row]
    cell.textLabel?.text = title
    cell.detailTextLabel?.text = subtitle
    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let vc = FavouritesViewController()
    navigationController?.pushViewController(vc, animated: true)
}

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCellEditingStyle.delete {
        offlineTitles.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
    }
}
}

【问题讨论】:

  • 不是重复的。在那个帖子中,有一个错误。在我的帖子中,没有错误,但是代码没有做我想要做的事情。
  • 顺便说一句,在你解决这个问题后,我看到你有一个删除操作。您可能也应该在那里更新您的模型对象并更新用户默认值。
  • 好的,谢谢提醒!我差点忘记了。
  • 对不起,错误的答案URL,它是这个问题的重复:stackoverflow.com/questions/25179668/…(你需要使用stringArray(forKey:)方法而不是array(forKey:)

标签: ios swift


【解决方案1】:

您似乎正在阅读cellForRowAt 中的用户默认值。这不仅效率低下(如果你有五个收藏夹,你会读五遍),而且是在错误的时间。例如,numberOfRowsInSection 会返回什么?到调用时,您还没有将用户默认值读入您的数组。

您应该将用户默认值读入viewDidLoad 中的数组(也可能在reloadTableData 中)。

【讨论】:

  • 那么如何在viewDidLoad中设置单元格的标题和副标题?
  • 对不起。我让你写代码是因为我不明白我该怎么做。
  • 您有代码可以将用户默认值读入一些本地userDefaultsTitleArray。所以(a)把它移到viewDidLoad; (b) 更新titlesArray,而不是更新userDefaultsTitleArray。然后cellForRowAt 不再需要任何用户默认的东西,只需使用titlesArraysubtitlesArray 相应地设置标题和副标题。
  • 再次抱歉。我终于明白了。非常感谢!
  • 解决了。我忘记使用defaults.set。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 2020-03-27
  • 2017-05-09
  • 1970-01-01
相关资源
最近更新 更多