I am using transition(from:to:duration:options:animations:completion:) method to move from one view controller to another. It happens fast but there is still a noticeable delay (about 1.5-2ms).
Here is my code:
func performTransition(to endController: UIViewController?) {
guard let endController, self.activeController != endController else { return }
let startTime = CACurrentMediaTime()
startVC.willMove(toParent: nil)
addChild(endVC)
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.transition(from: self.activeController, to: endController, duration: 0.0, options: [], animations: {
endController.view.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}) { [weak self] _ in
self?.activeController.removeFromParent()
endController.didMove(toParent: self)
self?.activeController = endController
let endTime = CACurrentMediaTime()
print("started at \(startTime)\nended at \(endTime)")
}
}
I added CACurrentMediaTime() to keep track of all the actions in the function, and noticed that delay occurs while executing a completion block. This is what it prints out:
started at 17011.142595500005
ended at 17011.178053125004
Figures differ, but you get the point. So my question is why is there a delay during the transition? I am still able to call any functions in other controllers while in my performTransition(to:) method and they get called immediately without delays, and the rest of the code keeps running. Even some UI elements get modified faster than the transition happens. I did add DispatchQueue block for some reason (I already forgot why, it’s definitely there for a reason lol, nothing changes if removed). Just to mention, the completion block is not @escaping, so I assume it should run in the right sequence on main thread, but it acts like it runs on a concurrent thread. Is it just how UIKit works under the hood, or there is something I don’t do or do wrong?