Попытка представитьначье представление не находится в иерархии окон - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь реализовать приложение VoIP с помощью Call Kit.По определенному сценарию принимается входящий звонок и завершается уже разговорный звонок.Как только вызов получен, я показываю свой интерфейс подключенного вызова в OutgoingCallController.

Так что в конкретном сценарии я пытаюсь отклонить уже подключенный OutgoingCallController, а затем снова пытаюсь представить новый OutgoingCallController с новыми подробностями входящего вызова.

Логика, которую я пытаюсь представить OutgoingCallController, заключается в следующих строках кода. Я вызываю этот метод в классе 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)
        });
    }

Конкретный код даты используется в целях регистрации, чтобы увидеть время выполнения этой строки кода.

В методе OutgoingCallWithAllController 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!

Это фрагмент кода, который я использую для отклонения моего старого OutgoingCallController. outgoingvc содержит ссылку на мой OutgoingCallController

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

Так как я пытаюсь удалить старый outgoingCallController и представить его снова, я могу понять, что я пытаюсь представить новый outgoingCallController на старомтот, который уже был отклонен.

Поэтому я попытался отложить представление нового контроллера, используя приведенный ниже фрагмент кода.

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 Попытка представить, чей вид не находится в иерархии окон

Я понимаю, что старый OutgoingCallController получен как вид сверху.

Ответы [ 3 ]

0 голосов
/ 04 марта 2019

Я исправил это, пытаясь получить самый верхний контроллер представления через интервал в 0,5 секунды.т.е. я вызываю свою функцию displayOutgoingScreen через интервал 0,5 секунды.В течение этого времени мой старый контроллер исходящих сообщений полностью отключается, и я вижу свой исходящий экран.

0 голосов
/ 06 марта 2019

Я думаю, что вы пытаетесь представить экземпляр контроллера исходящих представлений до полного закрытия другого экземпляра.

Отправляя с задержкой, вы только замаскировали эту проблему.

Я быпредложить вам, что, если у вас уже есть модально представленный контроллер представления - это стек, и вы отклоняете его, вы вызываете свою функцию представления внутри блока завершения функции dismiss.Таким образом, следующий контроллер представления будет представлен, когда предыдущий контроллер будет полностью удален из иерархии представления.

Но я все еще не думаю, что это хороший пользовательский опыт.

0 голосов
/ 01 марта 2019

Вы можете получить контроллер вида сверху, используя нижнее расширение:

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...