【问题标题】:UserDefault not being saved when going back to viewcontroller 1 and then back to viewcontroller 2返回视图控制器 1 然后返回视图控制器 2 时未保存 UserDefault
【发布时间】:2017-12-30 21:18:04
【问题描述】:

好的,所以我有两个视图控制器。一个视图控制器加载我的 Plist 上的所有单元格,第二个视图控制器打开单元格并向您显示描述。例如: 视图控制器 1: 狗 猫 鼠标

单击 Dog 单元格,它将带您进入 View Controller 2: 狗汪汪。

视图控制器1的写法:

  ovverride func prepare(for segue: UIStoryBoardSegue, sender: Any?) {
      if segue.identifier == "showDetail" {
         let animals: Animals
         if isFiltering() {
            animals = filteredData[indexPath.row]
            }
         else {
            animals = originalData[indexPath.row]
            }
          let controller = (segue.destination as! UINavigationController).topViewController as! SecondViewController
          controller.detailedAnimals = animals
          controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
          contrller.navigationItem.leftItemsSupplementBackButton = true
          }
    }
  }

这是我在 viewcontroller 2 中写的更新

var isFavorite : Bool = false

@IBAction func addToFav(_ sender:UIButton) {
    isFavorite = !isFavorite 
    UpdateButtonAppearance()
    saveData()
    }

 private func UpdateButtonAppearance(){
if isFavorite{
         let image = UIImage(named: "addFav")
         favButton.setImage(image, for: . normal)
         savedData()
         }

    else {
         let image = UIImage(named: "addFavFilled")
        favButton.setImage(image, for: . normal)
         savedData()
         }
 }

 ovveride func viewDidLoad(){
   UpdateButtonAppearance()
   saveData()
 }  

    //updated code
   func getFilePath () -> String {
   var path: [AnyObject] = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) as [AnyObject]
       let documentsDirectory: String = path[0] as! String
       let filepath = documentsDirectory.appending("Animals.plist")
       return filepath
   }

func saveData(){
    let myDict : NSMutableDictionary = NSMutableDictionary()
    myDict["fav"] = NSNumber(booleanLiteral: isFavorite)
    myDict.write(toFile: self.getFilePath(), atomically: true)
}

func getBool(){
    if FileManager.default.fileExists(atPath: self.getFilePath()) {
        var myDict = NSDictionary(contentsOfFile: self.getFilePath()) as! 
   [String:AnyObject]
        let myBool: Bool = myDict["fav"]!.boolValue
        isFavorite = myBool
    }

我看到一个关于如何更改 Plist 中的 bool 的教程,并以这种方式编写。代码可以编译,但我认为它不会改变 bool 值。所以在我的 Animals Plist 我有一个 Item 0 类型字典,第一个键称为 Animal,类型是字符串,值是“dog”,第二个键是 Description,类型是字符串,值是“dog go woof”,第三个键称为最喜欢的,类型是 Bool,值现在是 No,但我正在尝试将此值更改为 Yes,但它不起作用。也非常感谢您的评论,这很容易理解和理解。

【问题讨论】:

  • 也许你已经告诉你的图像视图总是加载空图像?你还没有说你的视图是如何排列的,所以视图控制器 2 可能正在卸载。当它再次加载回来时,它可能会忽略它的isFavorite,并且每次只使用空图像。
  • 那么如何检查viewcontroller是否每次都在卸载呢?为什么忽略 isFavorite?另一件事是,当我从 2 转到 ViewController 3 并返回到 ViewController 2 时,星星仍然被填满。但如果我回到 ViewController 1,然后再回到 2,星号又是空的。
  • 您的新代码仅将“fav”键和值写入 plist,而丢弃其他数据。在saveData 中,您创建一个新字典并添加一个“fav” NSNumber,然后将其写出来。相反,您将希望使用 plist 的现有内容(您似乎使用了“动物”字典的数组),并改为修改这些内容(例如,如果您正在更改第一项,请将“fav”键添加到第一项狗)。另外,如果我可以建议,请返回UserDefaults;它更简单,这就是它的设计目的。
  • 是的,但如果我执行 userdefaults 并放入 isfavorites 它会将所有动物都设为收藏夹,就像下面评论的神奇狗一样
  • 这样做:var animals = UserDefaults.standard.array(forKey: "animals" /* Or whatever you want this to be */) as! [[String : Any]]? ?? []; let dogIndex = animals.indices.first { animals[$0]["Animal"] as? String == "dog" /* Or whichever animal you want to favourite/unfavourite */ }!; animals[dogIndex]["fav"] = isFavorite; UserDefaults.standard.set(animals, forKey: "animals" /* Match the first UserDefaults call */)

标签: ios swift save default favorites


【解决方案1】:

当您返回第二个视图控制器时,星号未填充,因为您在 @IBAction func addToFav(_ sender:UIButton) 方法中设置了图像。那是当您点击按钮时。 您应该将这部分代码放在另一个方法中,也可以在 didLoad() 中调用。

第二个视图控制器应该是这样的:

var isFavorite = UserDefaults.standard.bool(forKey: "isFavorite")

func didLoad() {
     super.didLoad()
     updateButtonAppearance()
}

private updateButtonAppearance() {
     if isFavorite {
         let image = UIImage(named: "addFavFilled")
         button.setImage(image, for: . normal)
     }

     else {
         let image = UIImage(named: "addFav")
         button.setImage(image, for: . normal)
     }
}

@IBAction func addToFav(_ sender:UIButton) {
    isFavorite = !isFavorite
    UserDefaults.standard.set(isFavorite, forKey: "isFavorite")
    updateButtonAppearance()
}

还可以改进代码,使其不在addToFav 方法中的UserDefaults 中保存变量,而是在isFavourite 更改时保存。也许您稍后会想以另一种需要重复代码的方法更改isFavourite 的状态。

还请注意,您在 UserDefaults 中的 isFavourite 下保存了所有宠物的值。这意味着如果您偏爱一只宠物,则所有其他宠物都会受到青睐,反之亦然。考虑将用户默认值中的 bool 值替换为一个字典,该字典具有每个宠物的键和布尔值作为值。

【讨论】:

  • 仅供参考 - 您不需要致电 synchronize
  • 太神奇了,这条评论对我有很大帮助,但就像你说的那样,它确实将所有动物都变成了最爱,所以我在 plist 上做了一个布尔值,但我无法改变里面的值。所以我更新了上面的代码。再次感谢
猜你喜欢
  • 1970-01-01
  • 2013-01-08
  • 2017-02-13
  • 2020-02-18
  • 2016-06-20
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多