【问题标题】:Firebase PushViewController to push multiple timesFirebase PushViewController 推送多次
【发布时间】:2017-06-10 21:48:29
【问题描述】:

在我的项目中,我删除了情节提要中的所有转场并更改了所有

performSegue...

成为一个

pushViewController...

在我的应用程序中,75% 的时间都可以完美运行。但是,当我在 Firebase 方法中并尝试这样做时,VC 会在屏幕上多次闪烁。

我认为 Firebase 与它有关,因为我创建了一个简单的方法

func testDel() {
    if let addVC = self.storyboard?.instantiateViewController(withIdentifier: "AddCardVC") as? AddCardViewController {
        self.navigationController?.pushViewController(addVC, animated: true)
        print("foo")
    }
}

它完全按照预期工作,去了第二个 VC,就是这样......

在我发布我的代码之前,我为删除我原来的问题而道歉。我的编辑太多了。

到目前为止,我已经尝试将 push 包装在一个

DispatchQueue.main.async {...}

这没有效果。

我去了第二个 VC 并注释掉了所有函数并在任何有 pushVC 的行上放置断点只是为了查看它是否自动触发......

我在推送后立即在方法中添加了一条打印语句,它打印一次。我还在第二个 VC ViewWillAppear 中放置了一个打印语句,它被调用了 5 次。

我尝试注释掉我的推送代码并在情节提要上重新添加一个转场线并用老式的方式转场,它做了类似的事情,但是我在控制台中得到了一个日志说

开始/结束外观转换的不平衡调用 uiviewcontroller...

当我使用 push 时,这不会出现

我还在 SO 上找到了一篇较旧的帖子,其中有人建议了以下代码

var shouldPush = true

if let navigationController = self.navigationController {
for viewController in navigationController.viewControllers {
if viewController is AddCardViewController {
shouldPush = false
}
}
}

if shouldPush {
let addCrd = AddCardViewController(nibName: nil, bundle: nil)                       self.navigationController?.pushViewController(addCrd, animated: true)
}

这使得闪烁从大约 5 变为 2。仍然不是很好。

我的完整代码是这样的

// MARK: Delete Card with UIAlert

func deleteCard() {

    let alertController = UIAlertController(title: "Wait!", message: "This will completely remove this card from your account. All the services linked to this card will be removed. Your total fixed monthly expenses will also be erased!", preferredStyle: UIAlertControllerStyle.alert)

    let cancelAction = UIAlertAction(title: "Never Mind!", style: UIAlertActionStyle.cancel, handler: nil)

    let okAction = UIAlertAction(title: "I Understand!", style: UIAlertActionStyle.default) { (result: UIAlertAction) in

        let thisCard = self.ref.child("cards").child(self.thisCardIDTransfered)
        let thisCardInUsers = self.ref.child("users").child((self.user?.uid)!).child("cards").child(self.thisCardIDTransfered)

        thisCard.removeValue()
        thisCardInUsers.removeValue()

        let cardNode = self.ref.child("users").child((self.user?.uid)!).child("cards")

        cardNode.observeSingleEvent(of: .value, with: { (snapshot) in
            if snapshot.hasChildren() {

                if let walletVC = self.storyboard?.instantiateViewController(withIdentifier: "WalletVC") as? CardWalletViewController {
                    self.navigationController?.pushViewController(walletVC, animated: true)
                }

            } else {

                if let addVC = self.storyboard?.instantiateViewController(withIdentifier: "AddCardVC") as? AddCardViewController {
                    self.navigationController?.pushViewController(addVC, animated: true)
                    print("foo")
                }
            }
        })
    }

    alertController.addAction(cancelAction)
    alertController.addAction(okAction)

    self.present(alertController, animated: true, completion: nil)
}

【问题讨论】:

  • 您的 alertController 很可能会在项目从 firebase 中删除之前显示,这也意味着 walletVC 和 addVC 将在警报控制器之后显示。

标签: swift firebase


【解决方案1】:
cardNode.observeSingleEvent(of: .value, with: { (snapshot) in
            if snapshot.hasChildren() {
               ...

            } else {

            ...
        })

这个观察者可能会被多次调用,让你的视图被多次推送,也许检查快照包含的内容可以帮助你解决问题。我猜有时这个观察者会触发并且快照可能是 Null。

cardNode.observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.value is NSNull {
            //do Nothing
        } else {
           //check if it contains children
        }

我不建议使用观察者来决定你应该展示什么视图。尤其是当您正在收听 .value 时,因为它们可能会意外触发并且忘记删除观察者会导致许多错误。

【讨论】:

  • 为什么观察者会被多次调用?此外,观察者并没有指示显示哪个视图控制器 - 这是从节点加载数据的一次性操作,因此根据快照是否有任何子节点来指示显示哪个视图控制器。如果有孩子,用户可以通过 walletVC 进行交互,并且没有孩子可以通过 addCardVC 添加
【解决方案2】:

所以有人帮助了我,这让我很困惑,为什么在他看到我的项目的其余部分之前打印语句的顺序会发生......

在其他 ViewController 上,我有 Firebase 观察方法....当我推送到另一个 VC 时,我只是添加到堆栈中...该方法仍在后台运行,所以我有 2+ 个观察者在执行 pushViewController 。 .

我们最终将其中一些更改为 ObserveSingleEvent... 他告诉我,我们也可以这样做

viewDidDisappear

所以我想它帮助我更好地理解了应用程序的工作原理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    相关资源
    最近更新 更多