0

I am transitioning between views with the following code:

// Populate view2 here
UIView *theWindow = [_view2 superview];
[_view2 removeFromSuperview];

CATransition *animation = [CATransition animation];
[animation setDuration:0.25f];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction
            functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[[theWindow layer] addAnimation:animation forKey:@"SwitchToSecondView"];

This works however, the transition isn't completely smooth. I'm testing on iPhone4 device v5.1.1. Both views contain a UINavigationView, UIScrollView with around 20 subviews, I've considered populating the view after animation completes, but I would like to avoid this if possible. I would rate the smoothness of the transition 7/10.
How can i make this transition as smooth as possible?

abbood
  • 23,101
  • 16
  • 132
  • 246
GameDevGuru
  • 1,095
  • 2
  • 12
  • 27

2 Answers2

1

Your scrollview with the 20 subviews is what's causing your problem. Although I'll have to see the code itself to prove that, but this same problem happened with me when I tried to create a scroll view having many subviews, with the end result behaving similarly to UITableView (remember UITableView is a subclass of UIScrollView). note: proving that this is the cause is simple.. simply remove the 20 subviews of the UIScrollView and then run your animation.. if the lag is gone, then this is a sufficient proof.

Notice that UITableView can potentially have thousands of rows.. but the way it's designed is by reusing cells that no longer appear on the screen (ie recycling views from a pool, rather than making new views each time they are needed). in other words, it cannot afford to keep in memory more rows than what the screen will display, otherwise it will become laggy.

So go back to your scrollview with 20 subviews, and figure out a way to somehow only use subviews that are displaying on the screen, and instead of deallocing and allocing new subviews everytime, reuse them the same way UITableView does.

Please take a look at this interesting post of how a UITableView is actually created behind the scenes.. I'm sure it will give you ideas of how to optimize your own scrollview so as to a avoid the lag.

update: Based on the details of your view hiarchy in the comments.. this is what i would do

  1. i'd make the transition, but only display the n amount of UIImageViews that fit into the screen (ie 7 in your case).. in the UIAnimation completion block handler, I'd add the rest of the views
  2. If the above is not enough, I'll load the images into the views in the UIAnimation completion handler as well.
  3. If the above is not enough.. I'll also attach the 2 UIButtons and 2 UILabels to the subviews in the completion handler as well.

Do you see a pattern here? the idea is a focused trial and error: remove the most expensive operations one by one from the transition and place it after the transition is complete. Optionally, you can substitute the UIViews that have been pushed back to the end of the animation with fillers (ie think a placeholder for images, a spinner etc. The choice of these substitutions are really subject to UX principles and what you believe would be aesthetically pleasing to the user)

abbood
  • 23,101
  • 16
  • 132
  • 246
  • Removing the 20 subviews does fix the lag. As i mentioned in the post, i would like to avoid transitioning to a blank view. I'm leaning towards the idea of loading only the visible subviews before animation and the rest on completion. What are your thoughts on doing it this way? – GameDevGuru Sep 02 '13 at 03:39
  • @GameDevGuru I will honestly have to look at your code to give you any meaningful advice.. if for whatever reason you can't share the code.. you can at least visualize the UIView hirarchy or something.. – abbood Sep 02 '13 at 04:06
  • you can do lazy loading.. for example gradually introduce the views.. you can put a spinner or a `UIActivityIndicator` to indicate to the user that this is an expensive operation and so a little lag is to be expected.. there are tonnes of ways around this – abbood Sep 02 '13 at 04:07
  • The subviews are UIImageViews which contain their own subviews of 2 UIButtons and 2 UILabels. Hierarchy is `UIScrollView > 20 UIImageViews > 4 Subviews` – GameDevGuru Sep 02 '13 at 04:15
  • how many `UIImageViews` can fit in the screen? what is the size on average of each image (ie in terms of disk space? 1kb? 100kb?) – abbood Sep 02 '13 at 04:18
  • 7 fit on the screen (60 height). Each image is pulled from cached NSData <10kb – GameDevGuru Sep 02 '13 at 04:27
  • @GameDevGuru updated my answer.. now can i have my vote up and correct answer award? :p – abbood Sep 02 '13 at 04:32
0

You should run Instruments.app and see what's taking up your CPU time. Reducing that will also reduce stuttering and help smoothen out your animations.

zadr
  • 2,505
  • 18
  • 19