返回视图控制器 1 然后返回视图控制器 2 时未保存 UserDefault

Posted

技术标签:

【中文标题】返回视图控制器 1 然后返回视图控制器 2 时未保存 UserDefault【英文标题】:UserDefault not being saved when going back to viewcontroller 1 and then back to viewcontroller 2 【发布时间】: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 */) 【参考方案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 上做了一个布尔值,但我无法改变里面的值。所以我更新了上面的代码。再次感谢

以上是关于返回视图控制器 1 然后返回视图控制器 2 时未保存 UserDefault的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序关闭(然后启动)时返回“主”视图控制器

初始视图控制器标题更改为“返回”Swift

点击 UITabBar 时未调用子视图控制器的 viewDidDisappear

单击导航返回按钮,然后导航栏重叠相同的视图

viewWithTag 在子视图控制器中总是返回 nil

将js复杂数组传给mvc控制器,然后返回另一个视图