Pushing View Controller Twice

 ̄綄美尐妖づ 提交于 2019-12-21 06:07:40

问题


Within my app I'm having an issue with the following error:

Pushing the same view controller instance more than once is not supported

It's a bug report that's comeback from a few users. We've tried to replicate it but can't (double tapping buttons etc). This is the line we use to open the view controller:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let editView = storyboard.instantiateViewControllerWithIdentifier("EditViewController") as! EditViewController
editView.passedImage = image
editView.navigationController?.setNavigationBarHidden(false, animated: false)
if !(self.navigationController!.topViewController! is EditViewController) {
   self.navigationController?.pushViewController(editView, animated: true)
}

Anybody have any ideas? I've done a bit of research and most answers on Stack we've covered so are at a bit of a loss for how to investigate.


回答1:


Try this to avoid pushing the same VC twice:

if !(self.navigationController!.viewControllers.contains(editView)){
    self.navigationController?.pushViewController(editView, animated:true)
}



回答2:


As the pushViewController is asynchronous since iOS7, if you tap the button that push view controller too fast, it will be pushed twice. I have met such issue, the only way I tried is to set a flag when push is invoked (i.e - navigationController:willShowViewController:animated:) and unset the flag when the delegate of UINavigationController is called - navigationController:didShowViewController:animated:

It's ugly, but it can avoid the twice-push issue.




回答3:


In the function that does the push:

guard navigationController?.topViewController == self else { return }




回答4:


The completion block of CATransaction to the rescue :)

The animation of pushViewController(:animated:) is actually pushed onto the CATransaction stack, which is created by each iteration of the run loop. So the completion block of the CATransaction will be called once the push animation is finished.

We use a boolean variable isPushing to make sure new view controller can't be pushed while already pushing one.

class MyNavigationController: UINavigationController {
    var isPushing = false

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        if !isPushing {
            isPushing = true
            CATransaction.begin()
            CATransaction.setCompletionBlock {
                self.isPushing = false
            }
            super.pushViewController(viewController, animated: animated)
            CATransaction.commit()
        }
    }
}


来源:https://stackoverflow.com/questions/37829721/pushing-view-controller-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!