返回视图控制器 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的主要内容,如果未能解决你的问题,请参考以下文章