尝试在其视图不在窗口层次结构中<传出控制器:0x1040e9600><传出控制器:0x104042600>



我正在尝试使用呼叫套件实现VoIP应用程序。特定的方案被接受接听电话,并结束已经讲话。接听电话后,我在传出的CallController中显示我的连接的呼叫接口。

因此,在特定方案中,我试图解散已经连接的传出的CallController,然后尝试再次使用新的传入呼叫详细信息来介绍新的卸下CallController。

我试图提出的逻辑是这些代码行。我在CXProviderDelegate类中调用此方法。

func displayOutgoingScreen() throws {
        SwiftyBeaver.verbose("Starting displayOutgoingScreen!! ")
        let storyBoard = UIStoryboard.init(name: DiallerProperties.storyBoard, bundle: nil)
        let incomingcallController:OutgoingCallWithAllController = storyBoard.instantiateViewController(withIdentifier: "outgoingWithAll") as! OutgoingCallWithAllController
        //incomingcallController.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
        incomingcallController.number = AppDelegate().getIncomingCallNumber()
        SwiftyBeaver.verbose("Incoming call number is: (incomingcallController.number)")
        DispatchQueue.main.async(execute: { () -> Void in
            let keyWindow =  UIApplication.shared.keyWindow
            var controller:UIViewController = (keyWindow?.rootViewController)!
            while  controller.presentedViewController != nil {
                controller=controller.presentedViewController!
            }
            let dateFormatter : DateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
            let date = Date()
            let dateString = dateFormatter.string(from: date)
            let interval = date.timeIntervalSince1970
            print("presenting view here (dateString) (interval)!!")
            controller.present(incomingcallController, animated: true, completion: nil)
        });
    }

特定日期代码用于记录目的,以查看该行执行的时间。

在即将发出的CallWithAllController ViewWillDisAppear方法中,我使用了相同的日期逻辑来查看该特定方法何时被执行。

这是我收到的输出。

viewWillDisappear test 2019-03-01 13:34:32 1551427472.314188!!
presenting view here 2019-03-01 13:34:32 1551427472.324421!!

这是我在调试器日志中以上的警告消息。

2019-03-01 13:34:32.344713+0530 [710:214818] Warning: Attempt to present <OutgoingCallWithAllController: 0x1040e9600> on <OutgoingCallWithAllController: 0x104042600> whose view is not in the window hierarchy!

这是我用来解散我旧的外发callcontroller的代码。即将离开的VC 包含对我的卸下的CallController

的引用
AppDelegate.shared.outgoingvc?.dismiss(animated: false, completion: nil)

由于我试图驳回旧的外向callcontroller并再次提出,因此我可以理解,我正在尝试在已经被驳回的旧产品上介绍新的外发controller。

因此,我尝试使用以下代码延迟呈现的新控制器。

DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                //providing delay so that outgoing call controller has been closed
                action.fulfill()
                SwiftyBeaver.verbose("Executing after delay!!")
            }

但是,我仍然没有控制。我该如何解决这个特定问题?

如果以防万一已经研究过这样的问题:

警告:尝试在 *上呈现 *在窗口层次结构中的视图-Swift

swift 3尝试显示其视图不在窗口层次结构中的视图

我确实知道我将旧的外发callcontroller作为顶视图。

我通过尝试在0.5秒之后获取最佳视图控制器来修复它。
ie im在0.5秒的间隔后调用我的displayoutgoingscreen函数。


那个时候,我的旧传出控制器恰好被完全驳回,我可以看到我的传出屏幕。

我认为您试图在完全驳回另一个实例之前呈现传出视图控制器实例。

通过延迟派遣,您只掩盖了此问题。

我建议您,如果您已经有一个模态呈现的视图控制器是堆栈,并且您将其解雇,则在解雇功能的完成块中调用您的呈现功能。这样,当将前一个从视图层次结构完全删除时,将显示下一个视图控制器。

,但我仍然认为这是一个很好的用户体验。

您可以使用以下扩展名来获得顶视图控制器:

extension UIApplication {
    class func getTopMostViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return getTopMostViewController(base: nav.visibleViewController)
        }
        if let tab = base as? UITabBarController {
            if let selected = tab.selectedViewController {
                return getTopMostViewController(base: selected)
            }
        }
        if let presented = base?.presentedViewController {
            return getTopMostViewController(base: presented)
        }
        return base
    }
 }

使用此扩展程序在导航堆栈中使用以下代码获取最高视图控制器:

guard let topVC = UIApplication.getTopMostViewController() else {return}

使用顶视图控制器预设视图控制器:

DispatchQueue.main.async(execute: { () -> Void in
    topVC.present(incomingcallController, animated: true, completion: nil)
}

最新更新