Animate size of View keeping its bottom left point fixed - ios

I have a UIView at the bottom left of its superview, i.e.its frame is like
[myView setFrame:CGRectMake(0,superView.bounds.size.height-myViewHeight,myViewWidth,myViewHeight)];
I want to animate its size such that its bottom left point remains fixed at its position. I am not sure how to play with anchor point property of layers.
Currently I am increasing its size using the following lines of code.
[UIView animateWithDuration:0.2 animations:^{
[bottomLbl setFrame:CGRectMake(0, bottomView.bounds.size.height-250, 300, 250)];
This works fine but when I try to bring back to its original size, its bottom point gets lifted at the start of animation and settles down at the end of animation.

First define the point for the bottom left corner...
CGPoint bottomLeft = CGPointMake(0, 480); // this can be anything.
Then you need to define the sizes (big and small).
CGSize bigSize = CGSizeMake(280, 280);
CGSize smallSize = CGSizeMake(50, 50); // again, these can be anything.
Then animate them...
// create the rect for the frame
CGRect bigFrame = CGRectMake(bottomLeft.x, bottomLeft.y - bigSize.height, bigSize.width, bigSize.height);
CGRect smallFrame = CGRectMake(bottomLeft.x, bottomLeft.y - smallSize.height, smallSize.width, smallSize.height);
[UIView animateWithDuration:0.2
animations:^{
// set the rect onto the view
bottomLbl.frame = bigFrame;
// or
bottomLbl.frame = smallFrame;
}];
As long as you set the frame and the calculated end frames are correct and it's all done in one animation then the bottom left corner won't move.
If this doesn't help can you please post a video of what is happening (and all your animation code).
EDIT
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
// set the rect onto the view
bottomLbl.frame = bigFrame;
// or
bottomLbl.frame = smallFrame;
}
completion:nil];

Related

Move a UIView with start point

I have this code below who move my UIView to left:
- (void)viewDidLoad {
[super viewDidLoad];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:4];
int xOriginal = 91;
CGRect rect = imagem.frame;
int x = rect.origin.x;
int y = rect.origin.y;
int w = rect.size.width;
int h = rect.size.height;
if(x == xOriginal){
imagem.frame = CGRectMake(x+100, y, w, h);
}else{
imagem.frame = CGRectMake(x-100, y, w, h);
}
[UIView commitAnimations];
}
My coordinate of my view is x = 91 (Center of the superView), When I start my app my UIView start left and go to center, instead of center and go to right, Why this is happening?
How to make my UIView start in center (x=91) and go to right (91+100), instead of left to center?
[UIImageView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
imagem.frame=CGRectMake(imagem.frame.origin.x+100, imagem.frame.origin.y, imagem.frame.size.width, imagem.frame.size.height);
} completion:^(BOOL finished) {
//code for completion
NSLog(#"Animation complete");
}];
Autolayout and frame animations are not good friends. Try to animate constraints instead of directly the frame.
You can create outlets of your constraints, and set the constant property of the constraint in your code to move your views.
You also call -[view layoutIfNeeded] to refresh your constraints while in an animation block.
Else you can remove all of your view constraints and animate its frame fearlessly.
Initially image.frame = CGRectMake(91,100,20,20);
So imageview starting point is 0
[UIView animateWithDuration:5.0
animations:^{
//Animation code goes here
image.frame = CGRectMake(191,100,20,20); //Now imageview moves from 0 to 100
} completion:^(BOOL finished) {
//Code to run once the animation is completed goes here
}];
As the other poster says, you can't animate a view's frame in XIBs/storyboards that use AutoLayout.
Instead you have to animate a constraint that's attached to the view.
What you do is to create a constraint (or multiple constraints) and connect it to an IBOutlet. Then, in your animation code, you calculate the changes to the constraint(s) and change the constant for the appropriate constraints.
For example, if you wanted to shift the vertical position of a view, set up a constraint that sets the vertical position of your view, and link it to an IBOutlet called viewConstraint. Then you'd use code like this:
[myView animateWithDuration: .25
animations: ^
{
viewConstraint.constant -= shiftAmount;
[self.view layoutIfNeeded];
}
];

Animate UIView with Anchor Point and stretchable image

I'm trying to animate a bar chart where the images rise from the bottom. After a few hours, I'm seeing this is not an easy thing to achieve.
I simply want to do one thing:
Create an animation that scales up from a bottom center anchor point.
- (void)startCharts{
//set the stretchable images
UIImage* stretchGray = [UIImage imageNamed:#"rescueGrayChart"];
stretchGray = [stretchGray resizableImageWithCapInsets:UIEdgeInsetsMake(50, 0, 10, 0) resizingMode:UIImageResizingModeStretch];
self.grayChart.image = stretchGray;
//set the start frame and anchor point
CGRect gframe = self.grayChart.frame;
CGPoint bottomCenterGray = CGPointMake(CGRectGetMidX(gframe), CGRectGetMaxY(gframe));
self.grayChart.layer.anchorPoint = CGPointMake(0.5, 1);
[UIView animateWithDuration:5
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
//this creates the issue where the image scales outwards from center (see image)
CGRect frame = self.grayChart.frame;
frame.size.height = 300;
self.grayChart.frame = frame;
//this animates up from bottom, but stretches the image
/*
[CATransaction begin];
self.grayChart.layer.transform = CATransform3DMakeScale(1, 2, 1);
[CATransaction commit];
*/
}
completion:nil];
//readjust the frame
self.grayChart.layer.position = bottomCenterGray;}
** These images are screen shots taken during the animation
Thank you for your time.

iOS Minimize view and all subviews to top left

I have a UIView with a few subviews (and a few subviews in those). I am trying to minimize this entire view into the top left of the screen until it reaches a certain size (20 x 20) but am having trouble doing just that.
I first tried [UIView beginAnimations:nil context:nil]; but this didn't resize the subviews. Also, due to the padding and amount of other subviews, it would be very hard to set each subview frame to some new size and make it all work well.
I then tried this code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.myCardsCarousel.layer setAnchorPoint:CGPointMake(0.0f, 0.0f)];
[self.myCardsCarousel setTransform:CGAffineTransformMakeScale(0.0f, 0.0f)];
CGRect addCardsButtonFrame = self.addCardsButton.frame;
addCardsButtonFrame.size.height = 0.0f;
[self.addCardsButton setFrame:addCardsButtonFrame];
[UIView commitAnimations];
But this doesn't minimize to the top left of the screen. Instead, it minimizes to the dead center of the screen.
How can I anchor this to the top left of the screen? Also, how can I stop a CGAffineTransformMakeScale() when the view reaches a certain size?
One possible solution is to create a snapshot of the view, and animate the snapshot into the corner (assuming that it's ok for the minimized view to be static). The general sequence of events is
create a snapshot of the parent view into a memory bitmap
create a UIImageView from the snapshot
position the UIImageView in front of the parent view
hide the parent view using its hidden property
animate the UIImageView into the corner
To restore the view
animate the UIImageView back to its original location
unhide the parent view
remove the UIImageView and discard it
To start, you need a property for the UIImageView
#property (strong, nonatomic) UIImageView *snapshotView;
Here's the code to minimize the view
// create a snapshot image of the parent view
UIGraphicsBeginImageContextWithOptions( self.parentView.bounds.size, YES, 0 );
CGContextRef context = UIGraphicsGetCurrentContext();
[self.parentView.layer renderInContext:context];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// create a UIImageView from the snapshot
self.snapshotView = [[UIImageView alloc] initWithFrame:self.parentView.frame];
self.snapshotView.image = snapshot;
[self.view addSubview:self.snapshotView];
// hide the parent view in place, while animating the snapshot view into the corner
self.parentView.hidden = YES;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^
{
self.snapshotView.frame = CGRectMake( 0, 0, 20, 20 );
}
completion:nil];
Here's the code to restore the view
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^
{
// animate the snapshot view back to original size
self.snapshotView.frame = self.parentView.frame;
}
completion:^(BOOL finished)
{
// reveal the parent view and discard the snapshot view
self.parentView.hidden = NO;
[self.snapshotView removeFromSuperview];
self.snapshotView = nil;
}];

Making a map bigger on tap - iOS

If I were wanting to make a map on my app bigger on touch, how would I do that? Would I use core animation? Example, I want to change my map from 50px height to 70px height on touch.
Thanks :D
First you need to know when a user is touching the MKMapView and in the method that the user touched the map you do that:
[UIView animateWithDuration:0.5 animations:^{
CGRect rect = myMapView.frame;
rect.size = CGSizeMake(50, 70);//Set to Bigger Size
myMapView.frame = rect;
}];
And when the user leaves the touch from map:
[UIView animateWithDuration:0.5 animations:^{
CGRect rect = myMapView.frame;
rect.size = CGSizeMake(50, 50);//Set to Original Size
myMapView.frame = rect;
}];
If you want the resize animated then yes you can use core animation. However if you just want to resize, you can just redraw the map view by doing the following:
CGRect oldFrame = yourMapView.frame;
oldFrame.size.height = oldFrame.size.height + 20; //aka 50+20 = 70
yourMapView.frame = oldFrame;

How to lengthen the UISearchBar in x direction with animation?

I want to lengthen the right search bar 20 px to the left, and shorten left search bar 20 px to the right with animation. How can I do that?
CGRect leftFrame = self.leftSearchBar.frame;
//leftFrame.origin.x = leftFrame.origin.x - 20;
leftFrame.size.width = leftFrame.size.width - 40;
CGRect rightFrame = self.rightSearchBar.frame;
rightFrame.origin.x = rightFrame.origin.x - 40;
rightFrame.size.width = rightFrame.size.width + 40;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.leftSearchBar.frame = leftFrame;
self.rightSearchBar.frame = rightFrame;
[UIView commitAnimations];
It doesn't work. It first resizes views without animation, then moves the right view with animation.
Assuming you've not changed the anchor points, or anything like that, simply expanding the width will make it stretch to the right. Wrap this within a UIView animation block, and it should animate according to the specification within the question, as so:
UISearchBar* searchbar = ...; // However you've created your UISearchBar, we'll refer to it as 'searchbar'
CGRect searchFrame = searchbar.frame;
[UIView animateWithDuration:0.8
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
searchFrame.size.width += 30;
searchbar.frame = searchFrame;
}
completion:nil];
You'll need to make sure the += 30 doesn't get called more than once, as otherwise you'll be expanding by 30 points each time this is called. If you know the size before hand, you could simply substitute it with = size + 30, which is a safer bet incase you call the animation more than once.

Resources