I have a custom UIView with nested views of type UIImageView, UILabel and UIButton. The view is created in code like this:
- (void)setupView
{
popupView = [[UIView alloc] initWithFrame:CGRectMake(-116, -61, 247, 59)];
popupView.autoresizingMask = 63;
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bubble.png"]];
bgImageView.autoresizingMask = 63;
[popupView addSubview:bgImageView];
[bgImageView release];
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 8, 180, 20)];
textLabel.autoresizingMask = 63;
textLabel.font = [UIFont fontWithName:@"DefaultNormal" size:16];
textLabel.text = @"DYNAMIC TEXT";
[popupView addSubview:textLabel];
popupButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
[rightAccessoryButton setImage:[UIImage imageNamed:@"btn-tick.png"] forState:UIControlStateNormal];
popupButton.frame = CGRectMake(208, 8, 32, 32);
popupButton.autoresizingMask = 63;
[popupView addSubview:rightAccessoryButton];
}
I’ve set all their autoresizingMasks to 63 which is basically everything in the ON position (I don’t know a better way of doing that except putting all the constants on a huge line of code!). Then when they need to animate the popup, I do this:
- (void)animateIn
{
float pw = 247;
float ph = 59;
// set the view's initial position
popupView.frame = CGRectMake(-pw*0.005+8, -ph*0.01-2, pw*0.01, ph*0.01);
[self addSubview:popupView];
[UIView animateWithDuration:0.12 delay:0.0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionLayoutSubviews animations:^(void) {
popupView.frame = CGRectMake(-pw*0.55+8, -ph*1.1-2, pw*1.1, ph*1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^(void) {
popupView.frame = CGRectMake(-pw*0.475+8, -ph*0.95-2, pw*0.95, ph*0.95);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.075 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^(void) {
popupView.frame = CGRectMake(-round(pw/2-8), -ph-2, pw, ph);
} completion:nil];
}];
}];
}
Bit of a complicated looking animation, but effectively this is the same animation as the mapview callout view animation.
Only thing is, it works perfectly on iOS 5 devices, but on iOS 4 devices, everything is wrong! The label doesn’t show at all, the button appears and then flies off shrinking into the top right hand corder, and the background image stretches to the wrong size and in the wrong place.
Anyone else had any problems with animations in iOS 4? Do I have to do things differently than how they are currently in order to get it to work?
(1) Are you doing manual layout in a UIView subclass’s
layoutSubviewsimplemention? If not, you should not be usingUIViewAnimationOptionLayoutSubviewsin your options bitmask. I don’t know if that’s the problem but there’s no point adding extra sources of possible error.(2) When in doubt, use Core Animation. You could describe your animation sequence very handily as a nice CAAnimationGroup.