简体   繁体   中英

UIViewController dismiss issue

I want to wait until dismiss animation completes but I don't want to use many blocks in my code, so I wrote this function in UIViewController extension (almost like this worked several years ago for me):

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

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

so now instead of:

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

I was supposed to write:

viewController.dismissAnimated()
// code after completion

But it doesn't dismiss view controller and doesn't enter into completion block.

I tried different RunLoop modes, tried different dates, tried inserting RunLoop.current.run into while condition, it didn't work. Any ideas how to accomplish this?

Edit:

And it worked on iOS 9 or something like this (may be with some code changes, because I can't find my source code). I start RunLoop.current.run to avoid blocking main thread. For instance, if I put completed = true in DispatchQue.main.asyncAfter , it will work, the issue is with dismiss

I tried again because I was curious and this solution actually works for me:

@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 | Swift 4.2

It doesn't dismiss because your while !completed loop has stalled the main thread and the UI update happens on the main thread. What is wrong with running whatever code you need to run inside the dismiss completion closure?

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

If it's really just about not using blocks maybe this may be a solution?

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    if self.navigationController?.isBeingDismissed ?? self.isBeingDismissed  {
        print("Dismissal completed...")
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM