Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView Animation animates position but not width

I'm trying to transform a UISearchBar, like in Mobile Safari: touch in the search field and it grows while the location field shrinks.

My current animation to alter the width and position of the search field only animates the position: just before it slides to the right place, it simply snaps out to the right width. Here's my code:

[UIView beginAnimations:@"searchGrowUp" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationDelegate:self];

CGFloat findFieldWidth = findField.frame.size.width;
CGFloat urlFieldWidth = urlField.frame.size.width;
CGRect findFieldFrame = findField.frame;
CGRect urlFieldFrame = urlField.frame;

findFieldFrame.origin.x = findFieldFrame.origin.x - 150.0f;
findFieldFrame.size.width = findFieldWidth + 150.0f;
urlFieldFrame.size.width = urlFieldWidth - 150.0f;

urlField.frame = urlFieldFrame;
findField.frame = findFieldFrame;

[UIView commitAnimations];

I've modified this code slightly for the sake of presenting it here, but I hope this gives the gist.

Any guesses as to why this is happening would be appreciated!

Cheers, Aaron.

like image 584
Aaron Vegh Avatar asked Mar 23 '10 03:03

Aaron Vegh


4 Answers

I figured it out thanks to this post: Changing the size of the UISearchBar TextField?

Turns out the contents of a UISearchBar don't resize properly along with the outer layer. So you have to call -layoutSubviews: within the animation block after the frame is set on the searchbar. So the block ends like:

[findField setFrame:CGRectMake(findField.bounds.origin.y, findField.bounds.origin.y, findFieldWidth, findField.bounds.size.height)];
[findField layoutSubviews];

[UIView commitAnimations];

Props to Nick Farina!

like image 146
Aaron Vegh Avatar answered Sep 20 '22 02:09

Aaron Vegh


I had the same problem when trying to animate the width of a UISearchBar.

On iOS 4 and later, I found that using UIViewAnimationOptionLayoutSubviews as an option for

+[UIView animateWithDuration:delay:options:animations:completion:]

fixed it.

like image 33
otto Avatar answered Sep 20 '22 02:09

otto


The accepted answer works but according to Apple docs you "should not call this method". The clean solution is to use layoutIfNeeded method:

[UIView animateWithDuration:UINavigationControllerHideShowBarDuration
                      delay:0.f
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{

    [searchBar setFrame: ...
    [searchBar layoutIfNeeded];

    ...

Enjoy!

like image 42
Rudolf Adamkovič Avatar answered Sep 22 '22 02:09

Rudolf Adamkovič


Sorry this is a bit old, but I was running into a similar problem. I didn't want to use layoutSubviews because the documentation says you shouldn't call that method directly.

What I did to solve my problem was call sizeToFit on the subview within the animation block.

like image 24
xgalaxy Avatar answered Sep 21 '22 02:09

xgalaxy