【问题标题】:Toggling Property Does Not Show Change in Real Time切换属性不会实时显示更改
【发布时间】:2021-05-14 18:01:26
【问题描述】:

我有一个星形按钮,我想在点击时在填充和空之间切换。

我实现了以下功能:

func setStarButton() {
        
        let currentItem = data[currentItemIndex!]
        if currentItem.isStarred == true {
            starButton.setImage(UIImage(systemName: "star.fill"), for: .normal)
        }
        else {
            starButton.setImage(UIImage(systemName: "star"), for: .normal)
        }
        
    }

@IBAction func starTapped(_ sender: Any) {
        
        // Change the property in the Array
        var currentItem = item[currentItemIndex!]
        currentItem.isStarred?.toggle()
        
        // Update the database
        model.updateStarredStatus(currentItem.docID!, currentItem.isStarred!)
        
        // Update the button
        setStarButton()
        
    }

然后我在 viewDidAppear 中调用该函数:

override func viewDidAppear(_ animated: Bool) {
        
        // Set the status of the star button
        setStarButton()
        
    }

因此发生了以下预期行为:

  1. 只有当我第一次打开视图控制器时,星形按钮才会显示为正确的填充/未填充状态
  2. 当我点击星号按钮时,我的 Firebase Firestore 数据库会更新 Bool 值

我想要实现的是:当我继续实时点击它时,星形按钮在视图中变为填充/未填充。

有什么想法吗?我想我可能需要视图来监听数据库中的更改以进行视觉更新,但我不确定。非常感谢任何指导!

【问题讨论】:

  • 你的数组中的项目是类还是结构?
  • @Paulw11 它们是结构体!

标签: ios swift firebase boolean ibaction


【解决方案1】:

您的 item 数组包含结构。 Swift 中的结构是值类型。当您说var currentItem = item[currentItemIndex!] 时,您实际上将结构的副本分配给currentItem。然后在函数返回时修改并丢弃该副本。

稍后,当您在setStarButton 中访问data[currentItemIndex!] 时,您将访问原始的、未修改的结构。从 Firebase 刷新数组后,您会看到正确的值。

避免这个问题的一个简单方法就是去掉局部变量currentItem,直接对数组中的struct进行操作。

就个人而言,我会将相关值传递给setStarred;这样你就消除了访问 items 数组的重复代码。您还应该尽可能避免强制展开。对于像isStarreddocID 这样的属性是可选的也没有多大意义——一个项目要么加星标,要么不加星标。默认值falsenil 更有意义。 Firebase 中的所有文档都将有一个docID

func setStarButton(starred: Bool) {
     
    let imageName = starred ? "star.fill" : "star"

    starButton.setImage(UIImage(systemName: imageName), for: .normal)
 
}

@IBAction func starTapped(_ sender: Any) {
    guard itemIndex = self.currentItemIndex else {
        return
    }

    var isStarred = item[itemIndex].isStarred ?? false

    isStarred.toggle()
    item[itemIndex].isStarred = isStarred
        
        // Update the database
    model.updateStarredStatus(currentItem.docID!, isStarred)
        
        // Update the button
    setStarButton(starred: isStarred)
        
}

override func viewDidAppear(_ animated: Bool) {
        // Set the status of the star button
    if let itemIndex = self.currentItemIndex {
        setStarButton(starred: self.item[itemIndex].isStarred ?? false)
    } 
}

【讨论】:

  • 这是一个完美的解释。数据的分配是我的知识差距,你的其他观点是优化我的代码的好技巧。非常感谢!
猜你喜欢
  • 2013-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
  • 1970-01-01
相关资源
最近更新 更多