12

My aim is to make smooth animation started in the first view controller and end in the second view controller.

I'm experimenting with transition animation using object that conform to UIViewControllerAnimatedTransitioning and UIViewControllerTransitioningDelegate protocols. I set up two view controllers (VC) in the storyboard and connect them with segue (default show). I also made unwind segue method in the first VC and set up a button for it in the second VC.

I have strange problem. My object have methods

func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {

    self.presenting = true
    NSLog("start")
    return self
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    if presenting {
        NSLog("Animation Push")
        transitionPush(transitionContext)

    }
    else {
        NSLog("Animation Pop")
        transitionPop(transitionContext)

    }
}

I have two different methods for animation from first VC to second and from second to first VC. When I activate segue I have very strange delay between animationControllerForPresentedController and animateTransition methods. Sometimes it can be about 1 second, and my whole transition animation must be 1 second plus this unexpected delay is too big. Here is a log:

2015-02-08 19:52:33.528 MyApp[1318:119598] start
2015-02-08 19:52:33.979 MyApp[1318:119598] Animation Push

I don't know why this delay occur and if there a way to remove or reduce it? I tried to check if this could be my code, but I didn't find any prove of it. Feel free to ask for more info.

Dima Deplov
  • 3,688
  • 7
  • 45
  • 77
  • Were you able to resolve this? Also running into the same issue. – TWilly Apr 01 '15 at 18:46
  • I saw this post discussion the ios8 bug. I tried a few of the workarounds but haven't gotten anything to work yet. http://gotoanswer.com/?q=Animation+not+always+visible+from+animateTransition+in+UIViewControllerAnimatedTransitioning – TWilly Apr 01 '15 at 19:19
  • @TWilly right now I put this problem aside, but I will come back to it soon. But right now I have some thoughts about it. First of it I described in my answer for another topic in edit section http://stackoverflow.com/a/25618714/1207902 I also think that this could be my model, that processed data too long and this results in such delay. Anyway, I'll return to this problem and try to write an answer to it, when I'am done. But you can check out points that I specify. – Dima Deplov Apr 01 '15 at 21:04
  • @flinth I'm experiencing the same issue, there's about half a second delay between when I press the button to the time the animation starts, even with everything on the main thread – barndog Sep 02 '15 at 19:30
  • @startupthekid I change the animation method, for now, so I didn't find the problem in this case. But, I had one similar delay issue, my custom font that was not copied to the device. When I open VC with that font, system tried to find it and search all fonts (I think) for this one. When I fixed issue with font copying this delay disappeared. I fired a bug to apple, but I was unable to repeat the bug. But, this absent custom font delay totally was the problem in this case, so, check this, maybe you have something similar... I'll return to this problem soon and write an answer is I'll had one:) – Dima Deplov Sep 02 '15 at 21:46
  • I ran instruments on it and at least in my case, the slowdown is from the destination view controller having a lot of stuff to load in and the view controller is loaded before the transition begins. – barndog Sep 03 '15 at 02:23
  • @startupthekid in this case I can recommend to think about made some things asynchronous, it can greatly improve performance. Apple made their apps in this way, they show you UI first, and when content is load it shows. So, you don't wait for the content. – Dima Deplov Sep 03 '15 at 15:46
  • Hmmm yeah but an even better solution would be to preload the destination view controllers before the segue ever happens – barndog Sep 04 '15 at 09:57
  • @startupthekid, yes, maybe in your case, but again, do it in background thread. If you need more info about it, I can give you some links. – Dima Deplov Sep 04 '15 at 12:29

3 Answers3

4

I had the same problem. You're probably not triggering the animation from the main thread (presentViewController call).

This solved the issue for me (Objective-C code) :

dispatch_async(dispatch_get_main_queue(),
^{
    [self presentViewController:viewControllerToPresent
                   animated:YES
                 completion:nil];
});
Karim Benhmida
  • 195
  • 1
  • 1
  • 8
  • This didn't work for me. Maybe the main thread is already blocked for some reason which is preventing the transition from happening? or the button is somehow deactivated? – TWilly Apr 01 '15 at 18:46
  • this is strange - because i see main thread when call present, but your code helps me – sacred0x01 Nov 10 '15 at 19:55
2

I found solution (workaround) in discussion here, author – tamas.zahola

[self presentViewController:myViewController animated:YES completion:nil];
dispatch_async(dispatch_get_main_queue(), ^{}); // <--- this line
Sound Blaster
  • 4,778
  • 1
  • 24
  • 32
1

I've experienced this too. In my case I was seeing a 0.7s delay between the time I pushed a view controller with a custom animation transition and the time the animateTransition(using transitionContext:) method was called. The delay was highly perceptible to the end user.

The problem as it turns out was that the view controller I was pushing was loading some large images from the Asset Catalog on the main thread.

Preloading the images solved my problem.

par
  • 17,361
  • 4
  • 65
  • 80
  • 1
    Turns out, the general solution to this problem is to check every resource that will be used by destination view controller. Sadly, I didn't write clear edit / answer to this question, but mine problem occurred because of absent custom font in my bundle. The iOS check all font library to find it and if it isn't there, replace. There was a case of my delay. You faced basically the same problem - the resources takes too much time to load synchronously. – Dima Deplov Mar 17 '19 at 10:46
  • 1
    I wouldn't have considered the missing font case but yes, that makes perfect sense. Lots of little nuggets of wisdom are buried here and there on stackoverflow. Thank you! – par Mar 17 '19 at 19:21
  • 1
    In my case it was because I was calling sizeToFit() in a UIView component, which caused a big delay – jomafer Feb 23 '21 at 19:53