In this example.
I'm animating the PhotoViewerViewController's frame when I animate out the tabBarController (for fullscreen effect). The PhotoViewer uses a uiscrollview to generate the same sort of effect Apple's photos app does. For whatever reason sometimes it animates along with my PhotoViewer frame, and sometimes it doesn't.
You can see in the first example it jumps when increasing the frame size, but animates nicely when decreasing the frame size (and restoring the tab bar).
However in this example when the photo is vertical it jumps in both directions.
In both cases if I zoom in on the photo at all with the scrollview, it animates correctly in both directions.
I know the evidence is there, but I can't put my finger on what's happening here.
Here's my animation block:
void (^updateProperties) (void) = ^ {
self.navigationController.navigationBar.alpha = hidden ? 0.0f : 1.0f;
self.navigationController.toolbar.alpha = hidden ? 0.0f : 1.0f;
if (self.tabBarController) {
int height = self.tabBarController.tabBar.bounds.size.height;
for(UIView *view in self.tabBarController.view.subviews)
{
int newHeight;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientation)) {
newHeight = hidden ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.height - height;
} else {
newHeight = hidden ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.width - height;
}
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, newHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
CGRect newFrame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, newHeight);
[view setFrame:newFrame];
// update our VC frame with animation
[self.view setFrame:newFrame];
}
}
}
};
Code adapted from a post on SO: UITabBar wont hide
Full source on github.
In general, if animations sometimes work and sometimes don't, it's because in the latter case a delayed perform is causing them to be effectively cancelled by setting the property concerned to its final value.
In the particular case of UIScrollView
it often happens that -layoutSubviews
is called without animation one run loop after your animation blocks have closed. For this reason I usually try to avoid doing any layout in that method where I have a UIScrollView
in the view hierarchy (because particularly prior to iOS 5, UIScrollView
is really trigger-happy on setting itself to need layout).
I would recommend removing your call to -[EGOPhotoImageView layoutScrollViewAnimated:]
from -layoutSubviews
and add it to an overridden -setFrame:
instead.
If you can target iOS4 and above, take a look at UIViewAnimationOptionLayoutSubviews
too. Using a block-based animation with this as an option might just work without changing anything else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With