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;
Related
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.
At the moment I'm struggling to find a way to remove the offset glitch when I try to change the frame of a UIImageView which has a motionGroup attached to it.
This is the code for adding the motion effect:
UIInterpolatingMotionEffect *xAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:#"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
xAxis.minimumRelativeValue = #(-25.0);
xAxis.maximumRelativeValue = #(25.0);
self.motionGroup = [[UIMotionEffectGroup alloc] init];
self.motionGroup.motionEffects = #[xAxis];
[self.backImageView addMotionEffect:self.motionGroup];
now when i need to change the origin I do:
[self.backImageView removeMotionEffect:self.motionGroup];
[UIView animateWithDuration:0.3 animations:^{
CGRect frame = self.backImageView.frame;
frame.origin.x = self.originalBackImageViewOffset.x + 40;
self.backImageView.frame = frame;
} completion:^(BOOL finished) {
self.originalBackImageViewOffset = self.backImageView.frame.origin;
[self.backImageView addMotionEffect:self.motionGroup];
}];
this way there is a little glitch if the device is tilted. It appears right after removeMotionEffect: as the imageView transitions to it's original state and only then the frame changes. If the phone isn't tilted you won't even see the glitch (in the simulator).
If you don't remove the animationGroup then there is an even bigger glitch is you tilt the phone during the animation.
Does anyone know how to overcome this problem?
p.s. I don't have enough reputation to create a tag "UIMotionEffectGroup" or "UIMotionEffect".
Instead of animating the frame, apply a transform, then set the frame when the animation completes, without removing the motion effect:
[UIView animateWithDuration:0.3 animations:^{
self.backImageView.transform = CGAffineTransformMakeTranslation(40, 0);
} completion:^(BOOL finished) {
CGRect frame = self.backImageView.frame;
frame.origin.x = self.originalBackImageViewOffset.x + 40;
self.backImageView.frame = frame;
self.originalBackImageViewOffset = self.backImageView.frame.origin;
}];
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];
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.
I have to implement the rotate works like the photo app. Having the UIImageView inside a UIScrollView. and when device rotate, I want the image to rotate to landscape like Photo's. If the image is landscape-one, then it will fill the whole UIScrollView's width with the rotation animation. When the following code
[UIView animateWithDuration:0.36
animations:^(void){
[_imageView setTransform:CGAffineTransformMakeRotation(M_PI*90/180)];
_imageView.frame = CGRectMake(0, 0, 480, 320); //set the frame after the rotate
self.contentSize = CGSizeMake(480, 320); //set the content-size of the scrollview
}
completion:^(BOOL complete){
}];
But this does not work. rotate happens, but the position of the _imageView is not correct, or the image did not fill the width. Even I change the order frame and content-size before transform, still not correct.
What will be the correct approach to have this?
The WWDC 2010 Video: Designing Apps with Scrolls Views shows you exactly how to do this.
The correct answer, in my opinion, is to not animate the rotation yourself at all.
If you work according to the latest iOS 6 guidelines, then you just rearrange your views in the ViewController its layoutSubviews() method.
The source code that #CoDEFRo refers to is similar to the following, but here I've put it into the UIScrollView's delegate method scrollViewDidScroll:.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGSize boundsSize = scrollView.bounds.size;
CGRect frameToCenter = self.imageView.frame;
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
self.imageView.frame = frameToCenter;
}