How to repeat animation from current state not from startingstate? - iphone

I want to move my UIView from left to right in a repeatedly till the view not reached at the boundary of the right side. the below code running repeatedly but move only 5 points and repeat from starting point i want to repeat from last current state and the +5 to move further.
CGPoint pos = mover.center;
pos.x=25;
int count = 25;
[UIView beginAnimations:nil context:NULL];
pos.x=count;
[UIView setAnimationDuration:0];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationRepeatCount:INFINITY];
//[UIView setAnimationRepeatAutoreverses:YES];
// CGPoint pos = mover.center;
//pos.x +=5;
count = (pos.x+=5);
mover.center = pos;
i want to see object moving in +5 points interval.
and i'm new in objective c and iphone so please help me as fast as possible .
basically my task is move view on the border of the screen mean (left to right ,up to down ,right to left and down to up) means move view in in sequence and through border of the screen of simulator repeatedly.
i hope your answer helpful to me and other who is new in this technology(iPhone).
thank you very much.

To move view from one position to another i would set its frame inside animation block. Something like this would help you:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// `customView` is a UIView defined in .h file
customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
customView.backgroundColor = [UIColor redColor];
[self.view addSubview:customView];
[self rotateViewInSelfBoundary];
}
-(void)rotateViewInSelfBoundary
{
CGRect screen = [[UIScreen mainScreen] bounds];
// Top Left to top right
[UIView animateWithDuration:3.0f
animations:^{
[customView setFrame:CGRectMake(screen.size.width - customView.frame.size.width, 0, 100, 100)];
}
completion:^(BOOL finished)
{
// Top right to bottom right
[UIView animateWithDuration:3.0f
animations:^{
[customView setFrame:CGRectMake(screen.size.width - customView.frame.size.width, screen.size.height - customView.frame.size.height, 100, 100)];
}
completion:^(BOOL finished)
{
// bottom right to bottom left
[UIView animateWithDuration:3.0f
animations:^{
[customView setFrame:CGRectMake(0, screen.size.height - customView.frame.size.height, 100, 100)];
}
completion:^(BOOL finished)
{
// bottom left to top left
[UIView animateWithDuration:3.0f
animations:^{
[customView setFrame:CGRectMake(0, 0, 100, 100)];
}
completion:^(BOOL finished)
{
// call the same function again.
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(rotateViewInSelfBoundary) object:nil];
[self performSelector:#selector(rotateViewInSelfBoundary) withObject:nil afterDelay:0.0f];
}];
}];
}];
}];
}
Screen shots:

use UIViewAnimationOptionBeginFromCurrentState like
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionBeginFromCurrentState
animations:^{
//your animation
}
completion:nil];

If you want to move the view in a square, define the four CGPoint values it should animate between and then:
NSArray *values = #[[NSValue valueWithCGPoint:point0],
[NSValue valueWithCGPoint:point1],
[NSValue valueWithCGPoint:point2],
[NSValue valueWithCGPoint:point3],
[NSValue valueWithCGPoint:point0]];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
animation.values = values;
animation.duration = 5.0;
animation.repeatCount = HUGE_VALF;
[mover.layer addAnimation:animation forKey:#"moveAroundBorder"];
This will take care of all of the moving of the view with no further intervention on your part.
If you want to use the iOS 7 block-based key-frame animation, it would be:
[UIView animateWithDuration:5.0 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
[UIView animateKeyframesWithDuration:5.0 delay:0.0 options:UIViewKeyframeAnimationOptionRepeat | UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
[UIView addKeyframeWithRelativeStartTime:0.00 relativeDuration:0.25 animations:^{
mover.center = point0;
}];
[UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.25 animations:^{
mover.center = point1;
}];
[UIView addKeyframeWithRelativeStartTime:0.50 relativeDuration:0.25 animations:^{
mover.center = point2;
}];
[UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
mover.center = point3;
}];
} completion:nil];
} completion:nil];
Note the curious nesting of animateKeyframesWithDuration within the animateWithDuration. That's because the UIViewKeyframeAnimationOptionCalculationModeLinear curiously does not stop the "ease in / ease out" behavior, so you have to specify UIViewAnimationOptionCurveLinear on the outer animation block.

Related

Animation to Hide UIButton in iOS

In my application i want to give an animation to UIButtons, like the buttons will "fall out" of the screen when they hide.
I tried the following code but it didn't give me a good result.
[UIView animateWithDuration:1.5
animations:^{
S1Button.frame = CGRectMake(20, 10, 50, 10);
}];
[S1Button setHidden:YES];
break;
You can set new position and hide the button after animation.
[UIView animateWithDuration:0.9 animations:^{
tradeButton.frame = (CGRect){ CGPointMake(51, 150), tradeButton.bounds.size };
} completion:^(BOOL finished) {
tradeButton.hidden = YES;
// etc.
}];
Use the animation method which has a completion block and hide the button there. Currently your hide method runs immediately so you don't see the animation.
[UIView animateWithDuration:1 animations:^{
S1Button.frame = CGRectMake(20, 10, 50, 10);
} completion:^(BOOL finished) {
[S1Button setHidden:YES];
}]
Try this one
To fade out:
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 0;
} completion: ^(BOOL finished) {
button.hidden = YES;
}];
To fade in:
button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 1;
}];
[UIView animateWithDuration:0.25f
animations:^{
S1Button.frame = CGRectMake(20, 10, 50, 10);
}completion:^(BOOL completed){
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.3];
S1Button.alpha = 1;
[UIView commitAnimations];
}];
In your Code, The hidden property of Button is NOT animatable. When this animation block runs, your button will immediately hidden , but it will not fade/animate. The appropriate way to fade out a UIView is to animate its alpha property from 1.0 to 0.0 like this:
[UIView animateWithDuration:2.0
delay:0.0
options: UIViewAnimationCurveEaseOut
animations:^{S1Button.frame = CGRectMake(20, 10, 50, 10);S1buttonA.alpha = 0;}
completion:nil];
try this:
you hide the button before your animation completion, the no animation is visible. So, replace your code with this:
[UIView animateWithDuration:1.5 animations:^{
S1Button.frame = CGRectMake(20, 10, 50, 10);
} completion:^(BOOL finished) {
[S1Button setHidden:YES];
}];
break;

Multiple animations after each other

I'm having a problem I can't find any solution for it.
So basically, I'm having a compass that I want to "pop in"/"pop out" into the view, and then start to update heading, but heading stops updating after I dismiss/pop out the compass.
Like: user wants compass-> presses button-> compass pops up-> starting to rotate compass needle-> user don't want compass anymore/dismisses compass-> compass pops out of view.
So my question is: If i make one animation, the other animation stops, how do i make it possible for both to run after each other?
In showCompass:
(IBAction) showCompass:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
directionsArrow.center = CGPointMake(160, 410);
[UIView commitAnimations];
In locationManager:
float oldRadian = (-manager.heading.trueHeading * M_PI/180.0f);
float newRadian = (-newHeading.trueHeading * M_PI/180.0f);
CABasicAnimation *animation;
animation=[CABasicAnimation animationWithKeyPath:#"transform.rotation"];
animation.fromValue = [NSNumber numberWithFloat:oldRadian];
animation.toValue = [NSNumber numberWithFloat:newRadian];
animation.duration = 0.5f;
[directionsArrow.layer addAnimation:animation forKey:#"animateMyRotation"];
directionsArrow.transform = CGAffineTransformMakeRotation(newRadian);
In dismissCompass:
-(IBAction) dismissCompass {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
directionsArrow.center = CGPointMake(160, 410);
[UIView commitAnimations];
[locationManager stopUpdateHeading];
}
New code:
*Show:*
[UIView animateWithDuration:1.f
animations:^{
compassDial.center = CGPointMake(160, 504-92);
pushView.center = CGPointMake(160, 500-92);
//directionsArrow.center = CGPointMake(160, 502-92);
} completion:^(BOOL finished) {
directionsArrow.hidden = NO;
[locationManager startUpdatingHeading];
}];
In locationManager:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
float oldRadian = (-manager.heading.trueHeading * M_PI/180.0f);
float newRadian = (-newHeading.trueHeading * M_PI/180.0f);
CABasicAnimation *animation;
animation=[CABasicAnimation animationWithKeyPath:#"transform.rotation"];
animation.fromValue = [NSNumber numberWithFloat:oldRadian];
animation.toValue = [NSNumber numberWithFloat:newRadian];
animation.duration = 0.5f;
[directionsArrow.layer addAnimation:animation forKey:#"animateMyRotation"];
directionsArrow.transform = CGAffineTransformMakeRotation(newRadian);
Dismiss:
[UIView animateWithDuration:1.f
animations:^{
compassDial.center = CGPointMake(160, 700);
directionsArrow.center = CGPointMake(160, 700);
} completion:^(BOOL finished) {
[locationManager stopUpdatingHeading];
}];
Thanks in advance.
I'm assuming the two animations you want to happen at the same time are the rotation and the moving of the frame?
The easiest thing to do to ensure the animation is smooth and follows what you expect is to place the compass inside another view.
You can then animate the frame of the compass' parent to make the compass move in and out and apply the rotation just to the compass itself.
Show
[UIView animateWithDuration:1.f
animations:^{
compassContainer.center = CGPointMake(160, 410);
}];
Rotation
// The code you already have changing the transform of directionsArrow
Dismiss
[UIView animateWithDuration:1.f
animations:^{
compassContainer.center = CGPointMake(160, 410);
} completion:^(BOOL finished) {
[locationManager stopUpdateHeading];
}];
As Paul.s mentioned in the comments, that is not the current preferred way to do animations. And what you ask is really quite easy with the block method of animations. Have a look at the documentation, and here is a short example.
-(IBAction)animateDelete:(id)sender
{
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseIn
animations:^{
// Your first animation here...
}
completion:^(BOOL finished) {
// Do some stuff
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
// Your second animation here...
}
completion:^(BOOL finished) {
// Do some stuff
}
];
}
];
}

Resize view right-to-left with animation on iOS

I would like to resize UIView from right side to left (opposite).
Now I have view with rect like this: CGRectMake(100.f, 0.f, 100.f, 100.f);
[UIView animateWithDuration:0.5 animations:^{
view.frame = CGRectMake(0.f, 0.f, 200.f, 100.f);
}];
The problem is that animation is not nice. It bounces to the right (gets bigger) and than moves to location 0.0,0.0.
I would like to achieve the same effect like when resizing from left to right.
EDIT: code
- (void)resizeSearchBar:(int)type
{
//resize - bigger
if (type == 1) {
[UIView animateWithDuration:1.0 animations:^{
self.searchBar.frame = CGRectMake(0.f, 0.f, 280.f, 44.f);
}];
}
//resize - smaller
else {
[UIView animateWithDuration:1.0 animations:^{
self.searchBar.frame = CGRectMake(95.f, 0.f, 185.f, 44.f);
}];
}
}
EDIT 2
I've also tried to change View properties in IB like that:
Still no luck...
Got it to work with the hint from this answer: Can't animate the frame or bounds of a UISearchBar
The trick is to call [searchBar layoutSubviews]; in your animation block after setting the frame.
Here is what I got to work in my sample:
- (IBAction)resizeButtonTapped:(id)sender {
//resize - bigger
if (searchBar.frame.origin.x == 95) {
[UIView animateWithDuration:1.0 animations:^{
self.searchBar.frame = CGRectMake(0.f, 0.f, 280.f, 44.f);
[searchBar layoutSubviews];
}];
}
//resize - smaller
else {
[UIView animateWithDuration:1.0 animations:^{
self.searchBar.frame = CGRectMake(95.f, 0.f, 185.f, 44.f);
[searchBar layoutSubviews];
}];
}
}
I think this is useful to you just see bellow demo link...
https://github.com/ipup/PPRevealSideViewController?_tmc=UFw1P_Ai9brJd4WEpSlPbNrXBWOvsYZ6gNPi_derQik
i hope this help you..
:)
edited...
[UIView animateWithDuration:0.5
delay:4.0
options: UIViewAnimationOptionTransitionCrossDissolve
animations:nil
completion:^{
view.frame = CGRectMake(0.f, 0.f, 200.f, 100.f);}];
not sure but try this and also use different Animation like "UIViewAnimationOptionTransitionCrossDissolve",etc....
hope this help you....
It bounces because the duration is much less!!
Increase the duration ..and i think it will make it more clear how it animates
K try this
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
self.searchBar.frame = CGRectMake(0.f, 0.f, 280.f, 44.f);
}
completion:^(BOOL finished) {
}];
Chk here for Options

how to do a continuous recycling UIView animation

The following code move the the imageview from right to left once, but I want to do continously. move right to to left then move back to left offscreen and repeat right to left again.
imageview=[[UIImageView alloc] initWithFrame:CGRectMake(320, 200, 2635, 200)];
image=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"animal" ofType:#"png"]];
[imageview setImage:image];
[self.view addSubview:imageview];
[UIView beginAnimations:#"MoveAndStrech" context:nil];
[UIView setAnimationDuration:40]; //30
[UIView setAnimationBeginsFromCurrentState:YES];
CGPoint p, b, a, c, d,e;
p.x = 0;
p.y = 200;
imageview.center=p;
[UIView commitAnimations];
Add the following lines:
[UIView setAnimationRepeatCount: HUGE_VAL];
[UIView setAnimationRepeatAutoreverses: YES];
Or if you target iOS 4.0+ then blocked-based animations are preferred:
[UIView animateWithDuration:40.0f
delay:0.0f
options: UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionBeginFromCurrentState
animations: ^(void){imageview.center = CGPointMake(0, 200);}
completion:NULL];

Is it possible to removeFromSuperview with Animation?

I have 2 layer is top and bottom on my program
how can i remove top layer with animation or bring top layer to back is it possible?
The easiest is playing with frame and alpha before removing it.
You can get some cool effects
-(void)removeWithEffect:(UIView *)myView
{
[UIView beginAnimations:#"removeWithEffect" context:nil];
[UIView setAnimationDuration:0.5f];
//Change frame parameters, you have to adjust
myView.frame = CGRectMake(0,0,320,480);
myView.alpha = 0.0f;
[UIView commitAnimations];
[myView performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:0.5f];
}
iOS Update
You can now use blocks to perform your animation
[UIView animateWithDuration:0.5f
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];
If you're targetting iOS 4.0 upwards you can use animation blocks:
[UIView animateWithDuration:0.2
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];
(above code comes from Apple's UIView documentation)