【问题标题】:UIViewController dismiss issueUIViewController 关闭问题
【发布时间】:2019-06-16 02:06:54
【问题描述】:

我想等到关闭动画完成,但我不想在我的代码中使用很多块,所以我在UIViewControllerextension 中编写了这个函数(几年前对我来说几乎就像这样):

func dismissAnimated() {
   var comleted: Bool = false
   self.dismiss(animated: true) {
      comleted = true
   }

   while !comleted {
      RunLoop.current.run(mode: RunLoop.Mode.common, before: Date.distantFuture)
   }
}

所以现在而不是:

viewController.dismiss(animated: true) {
    // code after completion
}

我应该写:

viewController.dismissAnimated()
// code after completion

但它不会关闭视图控制器,也不会进入完成块。

我尝试了不同的 RunLoop 模式,尝试了不同的日期,尝试将 RunLoop.current.run 插入 while 条件,但没有成功。任何想法如何做到这一点?

编辑:

它可以在 iOS 9 或类似的系统上运行(可能有一些代码更改,因为我找不到我的源代码)。我启动RunLoop.current.run 以避免阻塞主线程。例如,如果我将 completed = true 放入 DispatchQue.main.asyncAfter ,它将起作用,问题在于 dismiss

【问题讨论】:

    标签: ios iphone swift uiviewcontroller runloop


    【解决方案1】:

    我又试了一次,因为我很好奇,这个解决方案实际上对我有用:

    @objc private func dismissTapped() {
    
        let dismissalTime = dismissAnimated()
        print("Dismissal took: %ld", abs(dismissalTime))
    
    }
    
    private func dismissAnimated() -> TimeInterval {
    
        let startDate = Date()
    
        var completed = false
        self.dismiss(animated: true) {
            completed = true
        }
    
        while !completed {
            RunLoop.current.run(mode: .default, before: .distantFuture)
        }
    
        return startDate.timeIntervalSinceNow
    
    }
    

    iOS 12.1.2 |斯威夫特 4.2

    【讨论】:

    • 谢谢,它有效,实际上它只有在我点击时才有效,如果我从 DispatchQueue.main 调用dismissAnimated(),它不起作用(dismiss 有效,但从未调用过完成),但我'会想办法解决的
    【解决方案2】:

    它不会关闭,因为您的 while !completed 循环已停止主线程并且 UI 更新发生在主线程上。在 dismiss 完成闭包中运行需要运行的任何代码有什么问题?

    self.dismiss(animated: true) {
        runSomeCode()
    }
    

    【讨论】:

    • 因为改进架构决策我最好使用没有阻塞的代码,无论如何问题是如何使这个决策起作用。它适用于 iOS 9 或类似的东西(可能有一些代码更改,因为我找不到我的源代码)。我运行 runLoop 以避免阻塞主线程。例如,如果我放入 DispatchQue.main.asyncAfter ,它将起作用,问题在于dismiss
    【解决方案3】:

    如果真的只是不使用块,也许这可能是一个解决方案?

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    
        if self.navigationController?.isBeingDismissed ?? self.isBeingDismissed  {
            print("Dismissal completed...")
        }
    }
    

    【讨论】:

    • 不,我需要使用 RunLoop 完成任务,因为之前的代码几乎像这样工作
    • 实际上找到了一个可行的解决方案。查看新答案。
    猜你喜欢
    • 1970-01-01
    • 2016-09-15
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2011-10-23
    • 1970-01-01
    相关资源
    最近更新 更多