How to stop and restart animation in UIView block animation - iphone

I have checked and tried variety of answers . But still it didn't work for me.
Here is my code,
-(void)animate {
[img1 startAnimating];
[UIView animateWithDuration:10
animations:^{
img1.transform = CGAffineTransformMakeTranslation(0.0, -1000);}];
[img2 startAnimating];
[UIView animateWithDuration:13
animations:^{
img2.transform = CGAffineTransformMakeTranslation(0.0, -1000);}];
}
I want to get animation started when i press one button and stop when i press another. It works fine for start and stop . but problem comes when i restart it by pressing on start button which calls this method again. Nothing happens when i call second time ??????

Transformation unable to perform twice
Hi you need to use the completion block to perform this animation,
Initialize like this some where else....
#interface YourClass()
{
CGAffineTransform trans1 ;
CGAffineTransform trans2 ;
}
#End
....
-(void)animate {
[_img1 startAnimating];
[UIView animateWithDuration:10
animations:^{
trans1 = _img1.transform; //
_img1.transform = CGAffineTransformMakeTranslation(0.0, -1000);} completion:^(BOOL finished) {
_img1.transform = trans1;
}];
[_img2 startAnimating];
[UIView animateWithDuration:13
animations:^{
trans2 = _img2.transform;
_img2.transform = CGAffineTransformMakeTranslation(0.0, -1000);} completion:^(BOOL finished) {
_img2.transform = trans2;
}];
}

Related

How to repeat animation from current state not from startingstate?

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.

Custom UIView doesn't get removed from superview when loaded again while animating

The question explains it all actually.
I load a custom UIView on top of my current view, animated, using this code:
- (void)showView
{
self.blurView.alpha = 0.f;
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
self.blurView.alpha = 1.f;
} completion:^(BOOL finished) {
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
self.blurView.alpha = 0.f;
} completion:nil];
}];
}
It works, but when I perform -(void)showView again while it is still animating, the custom view doesn't get removed from the screen.
It just stays like this:
I figured out what the problem was.
blurView is a public variable and every time I did -(void)showView it used the same variable, setting the alpha to 0.f just once, thus never changing the alpha of the first show.
I declared the variable blurView in the method itself and now it works because every blurView gets it's own pointer.
-(void)someMethod
{
//Create a live blur view
FXBlurView *blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
blurView.center = CGPointMake(self.view.window.frame.size.width / 2, self.view.window.frame.size.height / 2);
blurView.layer.cornerRadius = 20.f;
[self.view.window addSubview:blurView];
[self showView:(blurView)];
}
- (void)showView:(FXBlurView *)blurView
{
//Make full transparent before showing
blurView.alpha = 0.f;
//Start animation
[FXBlurView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
blurView.alpha = 1.f;
} completion:^(BOOL finished) {
if (finished)
{
//End animation
[FXBlurView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
blurView.alpha = 0.f;
} completion:nil];
}
}];
}
You should add to the top of your function this line:
[self.view.layer removeAllAnimations];
It will remove all of the active animations.
It doesn't work because you have implemented a delay, use animation block with delay - it will create animation keys that could be removed with this function above.
[UIView animateWithDuration:0.3 delay:0.0
options:UIViewAnimationOptionAllowUserInteraction
animations:^
{
// ...
} completion:NULL];

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
}
];
}
];
}

iPhone loading view "slide effect"

I would to achieve that when you request something in my app (like a button pressed or whatever) I would like it to appear a small rectangle that says "loading.." and when the loading is completed it disappear with a "slide up effect". I've made a simple mockups for describing well what I'm trying to achieve. Do you have any hint for me? Thanks.
NOTE: I don't want pull to refresh effect (the loading view appears without the screen scrolling, it appears for example when you send a comment)
UPDATE:
I've tried the Cirrostratus code:
- (IBAction)displayLoadingScreen:(id)sender
{
NSLog(#"pressed");
UIView *loadingView = [[UIView alloc] init];
loadingView.frame = CGRectMake(0,-40,320,40);
[loadingView setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:loadingView];
//animate in within some method called when loading starts
[UIView animateWithDuration:1.0
animations:^{
loadingView.frame = CGRectMake(0,0,320,40);
}
completion:^(BOOL finished) {
}];
for (int i = 0; i < 10000; i++) {
NSLog(#"%d", i);
}
//animate out within some method called when loading ends
[UIView animateWithDuration:1.0
animations:^{
loadingView.frame = CGRectMake(0,-40,320,40);
}
completion:^(BOOL finished){
}];
}
Why the loading view slide in after the for loop? If you try it, before it prints the for loop and after executes the two animations. Ideas?
UPDATE 2
- (void)stopLoading {
[UIView animateWithDuration:1.0
animations:^{
loadingView.frame = CGRectMake(0,-40,320,40);
}
completion:^(BOOL finished){
}];
}
- (void)startLoading {
loadingView.frame = CGRectMake(0,-40,320,40);
[loadingView setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:loadingView];
//animate in within some method called when loading starts
[UIView animateWithDuration:1.0
animations:^{
loadingView.frame = CGRectMake(0,0,320,40);
}
completion:^(BOOL finished) {
}];
sleep(5);
[self stopLoading];
}
- (IBAction)displayLoadingScreen:(id)sender
{
NSLog(#"button pressed");
[self startLoading];
}
loadingView.frame = CGRectMake(0,-40,320,40);
[loadingView setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:loadingView];
//animate in within some method called when loading starts
[UIView animateWithDuration:1.0
animations:^{
loadingView.frame = CGRectMake(0,0,320,40);
}
completion:^(BOOL finished){
}];
//animate out within some method called when loading ends
[UIView animateWithDuration:1.0
animations:^{
loadingView.frame = CGRectMake(0,-40,320,40);
}
completion:^(BOOL finished){
}];
What I would do is add a view in front of your other views with the loading design you want.
Then when the loading is finished (use a notification or just call a function of the view), slide it up with that kind of animation :
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionAllowUserInteraction
animations:^{
//change the frame to make the view go out of the screen
}
completion:^(BOOL finished){
//do whatever you want with the view (release it for instance)
}];
you can do it with the help of spinner else you take just view and set animation with its coordinate when you click on any object it will popup n your view and after completion of loading it you have to set '-' coordinate(frame) for your popup view hop it will hekp you......

animation blocks infinite loop - iphone

I'm having difficulty working with the animation blocks. I'm trying to have the first animation change the alpha of an image so that it flashes, then after 10 seconds disappears. the firstAnimation then moves to secondAnimation which does the same thing only to a different image. the process then repeats itself infinitely.
I've been working w/ this for a while now and cannot make it repeat infinitely. Another problem I had was having this animation process delay - so that it begins after 20 seconds, enough time for an audio file to play.
- (void) firstAnimation {
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:1.0 delay:10.0 options:options animations:^
{
myImage.alpha = 0.0;
myImage.alpha = 1.0;
}
completion:^(BOOL finished){
[self secondAnimation];
}
];
}
thanks as always, for any help. I've searched for example code and tutorials but all I found is basically what I'm doing in the code above.
I think you have to set the initial value of your alpha outside the animation block and only the value you want it to animate to inside the block.
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
myImage.alpha = 0.0;
[UIView animateWithDuration:1.0 delay:10.0 options:options animations:^
{
myImage.alpha = 1.0;
}
animateImageWithCount:(int)aCount{
if( aCount >= [imageArray count]){
NSLog(#"Done all images");
return;
}
UIImage *myImage = [ImageArray objectAtIndex:aCount];
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
myImage.alpha = 0.0;
[UIView animateWithDuration:1.0 delay:10.0 options:options animations:^{
myImage.alpha = 1.0;
}
completion:^(BOOL finished){
[self animateImageWithCount:(aCount+1)];
}];
}