Avoid creation of multiple ViewController instances, iOS Swift

此生再无相见时 提交于 2019-12-13 14:02:58

问题


In AppDelegate, the below function gets called whenever VoIP call (push notification) is received thereby creating multiple instances of "VideoCallViewController"

I've used deinit (in VideoCallViewController) as shown below, to check if the previous instance of "VideoCallViewController" was being de-initialised before a new instance of "VideoCallViewController" is created, to my surprise print("Deinitializing VC) wasn't called, leaving the instance in memory.

How can I show VideoCallViewController with its Navigation Controller if an instance of VideoCallViewController already exists from AppDelegate.

In VideoCallViewController

deinit {
  print("Deinitializing VC)
}

In AppDelegate

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    videoVC = storyboard.instantiateViewController(withIdentifier: "VideoCallViewController") as! VideoCallViewController

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = videoVC
    self.window?.makeKeyAndVisible()

}

回答1:


Possible solution: Create singleton holding reference to nullable window, responsible for video calls flow. On notification change visible windows. On call end - return to the application main window.

E.G. :

class VideoCallManager {
    //MARK: - Singleton
    static let sharedInstance = VideoCallManager()
    private init() {}

    private var videoCallWindow: UIWindow?

    func navigateToVideoCallViewController() {
        if let window = self.videoCallWindow, window.keyWindow {
             //VideoCallViewController is displayed at the moment.
             return
        }

        videoCallWindow = UIWindow.init(frame: UIScreen.mainScreen().bounds)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        videoVC = storyboard.instantiateViewController(withIdentifier: "VideoCallViewController") as! VideoCallViewController

        self.videoCallWindow?.rootViewController = videoVC
        self.videoCallWindow?.makeKeyAndVisible()
    }

    func returnToWindowOfAppDelegate() {
        if let window = self.videoCallWindow, window.keyWindow {
            (UIApplication.sharedApplication().delegate as? AppDelegate)?.window?.makeKeyAndVisible()

            self.videoCallWindow = nil
        }
    }
}

And your method would look like:

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
    VideoCallManager.sharedInstance.navigateToVideoCallViewController()
}



回答2:


You can create a lazy var in your AppDelegate

lazy var videoVC: UIViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    return storyboard.instantiateViewController(withIdentifier: "VideoCallViewController")
}()

Then in your pushRegistry:

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = self.videoVC
    self.window?.makeKeyAndVisible()

}


来源:https://stackoverflow.com/questions/46466660/avoid-creation-of-multiple-viewcontroller-instances-ios-swift

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