I'm trying to stack two animations. I use the same UIImage in my code for both images.
I start by determining (first line) WHAT image to load.
NSString *imageName = (self._handleToSectionModel.calculatorState == CALCULATOR_OPENED)?
[NSString stringWithString:#"1_dg_please_see_warning_2lines.png"] :
[NSString stringWithString:#"1_dg_warnings_landing_page.png"];
I want to fade OUT the current image, and load the new image and FADE it in. Obviously when I
execute this it only really animates the second one. What's the correct way to stack animations
to the same View so they both run fully?
UIImage *image = [UIImage imageNamed:imageName];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0f];
self.warningImage.alpha = 0.0f;
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0f];
self.warningImage.alpha = 1.0f;
self.warningImage.image = image;
[UIView commitAnimations];
EDIT / UPDATE:
SOLVED:
[UIView animateWithDuration:1.0 animations:^{ self.warningImage.alpha = 0.0f; } completion:^(BOOL finished){
[UIView animateWithDuration:1.0 animations:^{ self.warningImage.alpha = 1.0f; self.warningImage.image = image; } completion:^(BOOL finished){}];
}];
Thanks to the link in my comment!
[UIView animateWithDuration:1.0 animations:^{ self.warningImage.alpha = 0.0f; } completion:^(BOOL finished){
[UIView animateWithDuration:1.0 animations:^{ self.warningImage.alpha = 1.0f; self.warningImage.image = image; } completion:^(BOOL finished){}];
}];
Related
I have a view controller called ViewController in which I have two methods, hideAd and showAd:
// Method is called when the iAd is loaded.
-(void)showAd:(ADBannerView *)banner {
// Creates animation.
[UIView beginAnimations:nil context:nil];
// Sets the duration of the animation to 1.
[UIView setAnimationDuration:1];
// Sets the alpha to 1.
// We do this because we are going to have it set to 0 to start and setting it to 1 will cause the iAd to fade into view.
[banner setAlpha:1];
// Performs animation.
[UIView commitAnimations];
}
// Method is called when the iAd fails to load.
-(void)hideAd:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
// Creates animation.
[UIView beginAnimations:nil context:nil];
// Sets the duration of the animation to 1.
[UIView setAnimationDuration:1];
// Sets the alpha to 0.
// We do this because we are going to have it set to 1 to start and setting it to 0 will cause the iAd to fade out of view.
[banner setAlpha:0];
// Performs animation.
[UIView commitAnimations];
}
I would like to be able to call these methods from my skscenes, two of which called startview and gameview. I tried implemeting this solution: How to show iAd on a certain SKScene and hide it on the other one, but setDelegate does not work for me. In what way can I hide and show my banner iads?
Instead of chaining alpha, move its position.
-(void)showBannerView
{
if (_adBannerViewIsVisible)
{
return;
}
if (_adBannerView)
{
_adBannerViewIsVisible = true;
CGRect frame = _adBannerView.frame;
if(app_dsp.isBannerOnTop)
{
frame.origin.x = 0.0f;
frame.origin.y = -_adBannerView.frame.size.height;
}
else
{
frame.origin.x = 0.0f;
frame.origin.y = self.size.height;// - _adBannerView.frame.size.height;
}
_adBannerView.frame = frame;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
if(app_dsp.isBannerOnTop)
{
frame.origin.x = 0.0f;
frame.origin.y = 0.0f;
}
else
{
frame.origin.x = 0.0f;
frame.origin.y = self.size.height - _adBannerView.frame.size.height;
}
_adBannerView.frame = frame;
[UIView commitAnimations];
}
}
-(void)hideBannerView
{
if (!_adBannerViewIsVisible)
{
return;
}
if (_adBannerView)
{
_adBannerViewIsVisible = false;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect frame = _adBannerView.frame;
if(app_dsp.isBannerOnTop)
{
frame.origin.x = 0.0f;
frame.origin.y = -_adBannerView.frame.size.height ;
}
else
{
frame.origin.x = 0.0f;
frame.origin.y = self.size.height ;
}
_adBannerView.frame = frame;
[UIView commitAnimations];
}
}
I've looked at several posts, including [this one].1 This is exactly what I want to do, but I cannot get it to work.
I want to show the user that they have pressed a record button, and that they will need to press it again to stop recording.
So far, the code for the start recording method looks like this:
NSLog(#"DetailVC - recordAudio - soundFilePath is %#", soundFile);
[audioRecorder prepareToRecord];
recording = YES;
NSLog(#"start recording");
NSLog(#"1");
//[autoCog startAnimating];
[audioRecorder recordForDuration:120];
recording = NO;
//Start a timer to animate the record images
if (recording == YES) {
toggle = FALSE;
timer = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector: #selector(toggleButtonImage:)
userInfo: nil
repeats: YES];
//UIImage *changeImage = [UIImage imageNamed:stopButtonFile];
//[recordButton setImage:changeImage forState:UIControlStateNormal];
//[timer invalidate];
//timer = nil;
NSLog(#"2");
}
and the toggleButton method looks like this:
- (void)toggleButtonImage:(NSTimer*)timer
{
NSLog(#"%s", __FUNCTION__);
if(toggle)
{
NSLog(#"1");
/*
[UIView beginAnimations];
recordButton.opacity = 0.0;
[recordButton setAnimationDuration: 1.5];
[recordButton commitAnimations];
[recordButton setImage:[UIImage imageNamed:#"record.png"] forState: UIControlStateNormal];
*/
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; //delete "EaseOut", then push ESC to check out other animation styles
[UIView setAnimationDuration: 0.5];//how long the animation will take
[UIView setAnimationDelegate: self];
recordButton.alpha = 1.0; //1.0 to make it visible or 0.0 to make it invisible
[UIView commitAnimations];
}
else
{
NSLog(#"2");
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; //delete "EaseOut", then push ESC to check out other animation styles
[UIView setAnimationDuration: 0.5];//how long the animation will take
[UIView setAnimationDelegate: self];
recordButton.alpha = 0.0; //1.0 to make it visible or 0.0 to make it invisible
[UIView commitAnimations];
//[recordButton setImage:[UIImage imageNamed:#"stopGrey.png"] forState: UIControlStateNormal];
}
toggle = !toggle;
}
I get to see the logs showing that the loop is iterating, but:
the images do not switch, and
the operation is not running in parallel with the record method.
I would appreciate any ideas as to how to proceed.
Expanding on Ashley's answer, I'd go with something more like this:
- (IBAction)record:(id)sender {
self.recording = !self.recording;
if (!self.recording) {
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.recordButton.alpha = 1.0f;
}
completion:^(BOOL finished){
}];
} else {
self.recordButton.alpha = 1.0f;
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.recordButton.alpha = 0.0f;
}
completion:^(BOOL finished){
}];
}
}
Try this:
- (IBAction)record:(id)sender
{
self.recording = !self.recording;
[self toggleButton];
}
- (void) toggleButton
{
if (!self.recording) {
self.recordButton.alpha = 1.0;
return;
}
[UIView animateWithDuration: 0.5
delay: 0.0
options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.recordButton.alpha = !self.recordButton.alpha;
}
completion:^(BOOL finished) {
[self toggleButton];
}];
}
I have an animation that plays fine. But at the end of the animation, the animation stops. I want the animation to loop. How can I do this? Here is my code:
- (void) startTicker
{
if (self.timerIsRunning) return;
self.timerIsRunning = YES;
NSTimer *newTimer = [NSTimer timerWithTimeInterval:(0.1) target:self selector:#selector(onTimer:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:newTimer forMode:NSDefaultRunLoopMode];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:100.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDelay:0.0];
[UIView setAnimationDidStopSelector:#selector(moveToLeft:finished:context:)];
[UIView commitAnimations];
}
-(void)moveToLeft:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
imageView.left = 800;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:100.0];
[UIView setAnimationDelay:0.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self cache:YES];
imageView.right = 800;
[UIView setAnimationDidStopSelector:#selector(moveToLeft2:finished2:context2:)];
[UIView commitAnimations];
}
For loop animation the best way is to use block animations which are a part of UIView.
When calling the method:
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
The "option" you probably want is UIViewAnimationOptionAutoreverse and combined with the UIViewAnimationOptionRepeat
For example: (loop blinking red border)
[UIView animateWithDuration:2.0f delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
[redBorder setAlpha:0]; //first part of animation
[redBorder setAlpha:0.5]; //second part of animation
} completion:nil];
I would like to rotate an UIImageView clockwise around his center after pressing a button (360 degrees)... It should be an animation... So its getting a steering wheel, and it should rotate by itself visible for the user...
I saw there are many ways to do that, but nothing worked for me... :-)
The CABasicAnimation, do I have to add a framework for this?
Could someone give me a sample code, for rotating an UIImageView around its center for (360 degrees) that works?!?
thank you in advance
Hear given below i do same thing ...... but my requirement is when touchBegin that View will be rotate 360 degree ... it may help to you.....
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
self.userInteractionEnabled=YES;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
[UIView commitAnimations];
[delegate changeImage:self];
}
-(void)changeImage:(DraggableImages *)selectedView
{
count++;
clickCounter++;
counterLable.text=[NSString stringWithFormat:#"%i",clickCounter];
selectedView.image=[images objectAtIndex:selectedView.tag];
if (count==1) {
firstSelectedView=selectedView;
}
if (count==2) {
self.view.userInteractionEnabled=NO;
secondSelectedView=selectedView;
count=0;
[self performSelector:#selector(compareImages) withObject:nil afterDelay:0.7];
}
}
-(void)compareImages
{
if (firstSelectedView.tag==secondSelectedView.tag)
{
matches++;
//NSLog(#"%#",matches);
Score=Score+10;
scoreLable.text=[NSString stringWithFormat:#"%d",Score];
firstSelectedView.alpha=0.5;
secondSelectedView.alpha=0.5;
self.view.userInteractionEnabled=YES;
if(matches==[images count])
{
[timer invalidate];
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:[NSString stringWithFormat:#"Do you want to countinue?"] delegate:self cancelButtonTitle:nil otherButtonTitles:#"YES",#"NO", nil];
[alertView show];
[alertView release];
}
}
else {
Score=Score-1;
scoreLable.text=[NSString stringWithFormat:#"%d",Score];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:firstSelectedView cache:YES];
firstSelectedView.image=[UIImage imageNamed:#"box.jpg"];
[UIView commitAnimations];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:secondSelectedView cache:YES];
secondSelectedView.image=[UIImage imageNamed:#"box.jpg"];
[UIView commitAnimations];
firstSelectedView.userInteractionEnabled=YES;
secondSelectedView.userInteractionEnabled=YES;
self.view.userInteractionEnabled=YES;
}
}
You need to add the QuartzCore framework, and you can read more about CABasicAnimation.
Some Tutorials
Interrupting Animation Progress
Slider Based Layer Rotation
CABasicAnimation basics
Core Animation Paths
Upon button press invoke this method:
- (void) animate{
CABasicAnimation *imageRotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
imageRotation.removedOnCompletion = NO; // Do not turn back after anim. is finished
imageRotation.fillMode = kCAFillModeForwards;
imageRotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
imageRotation.duration = 1.5;
imageRotation.repeatCount = 1;
[yourImageView.layer setValue:imageRotation.toValue forKey:imageRotation.keyPath];
[yourImageView.layer addAnimation:imageRotation forKey:#"imageRotation"];
}
and yes as WrightsCS has stated, you will need QuartzCore framework included in your project. Dont forget the import statement:
#import <QuartzCore/QuartzCore.h>
I'm trying to slide a UIImageView into a UIView, and fade it in at the same time. And then I want it to fade and slide out.
The code below should do this, but it doesn't.
Instead, the leftArrow view is at full alpha when it slides in. So the first animation is skipping the alpha fade-in. Then the second animation just fades it out, it does not move the leftArrow view. I've tried lots of variations (using bounds instead of frames, doing the animation in a class method (as opposed to an instance method), and I cannot determine why the view seems to arbitrarily pick one thing to do rather than the other, or both.
Maybe I just need fresh eyes.
TIA,
Mike
- (void) flashHorizontalArrowsForView: (UIView *)view {
DebugLog(#" flashHorizontalArrows");
float duration = 1.5f;
// create the views
UIImageView *leftArrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"leftCouponDetailArrow.png"]];
leftArrow.frame = CGRectMake(0 -leftArrow.image.size.width,
HORIZONTAL_ARROW_START_Y,
leftArrow.image.size.width,
leftArrow.image.size.height);
[view addSubview:leftArrow];
leftArrow.alpha = 0.0f;
// animate them in...
[UIView beginAnimations:#"foo" context:leftArrow];
[UIView setAnimationDelay: 0.0f ]; // in seconds
[UIView setAnimationDuration: duration ];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDidStopSelector:#selector(animationReallyDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
leftArrow.alpha = 1.0f;
CGRect LFrame = leftArrow.frame;
LFrame.origin.x += LFrame.size.width; // move it in from the left.
leftArrow.frame = LFrame;
[UIView commitAnimations];
// and animate them out
// delay enough for the first one to finish
[UIView beginAnimations:#"bar" context:leftArrow];
[UIView setAnimationDelay: duration+0.05 ]; // in seconds
[UIView setAnimationDuration: duration ];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDidStopSelector:#selector(animationReallyDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
leftArrow.alpha = 0.0f;
CGRect LLFrame = leftArrow.bounds;
LLFrame.origin.x -= LLFrame.size.width; // move it off to the left.
leftArrow.bounds = LLFrame;
[UIView commitAnimations];
}
Solution is simple - when the first animation finishes, have it call another method, like horizontal2, and in horizontal2, do the animate_them_out part.
- (void) flashHorizontalArrowsForView: (UIView *)view{
DebugLog(#" flashHorizontalArrows");
self.theView = view;
float duration = 1.5f;
// create the views
UIImageView *left = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"leftCouponDetailArrow.png"]];
self.leftArrow = left;
[left release];
leftArrow.tag = LEFT_ARROW_TAG;
leftArrow.frame = CGRectMake(0 -leftArrow.image.size.width,
HORIZONTAL_ARROW_START_Y,
leftArrow.image.size.width,
leftArrow.image.size.height);
[theView addSubview:leftArrow];
leftArrow.alpha = 0.0f;
UIImageView *right = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"rightCouponDetailArrow.png"]];
self.rightArrow = right;
[right release];
rightArrow.tag = RIGHT_ARROW_TAG;
rightArrow.frame = CGRectMake(view.frame.size.width, // -leftArrow.image.size.width,
HORIZONTAL_ARROW_START_Y,
leftArrow.image.size.width,
leftArrow.image.size.height);
[theView addSubview:rightArrow];
rightArrow.alpha = 0.0f;
// --------------------------------------------
// animate them in...
[UIView beginAnimations:#"foo" context:nil];
[UIView setAnimationDelay: 0.0f ]; // in seconds
[UIView setAnimationDuration: duration ];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDidStopSelector:#selector(horizontalPart2)];
[UIView setAnimationDelegate:self];
leftArrow.alpha = 1.0f;
rightArrow.alpha = 1.0f;
CGRect LFrame = leftArrow.frame;
LFrame.origin.x += LFrame.size.width; // move it in from the left.
leftArrow.frame = LFrame;
CGRect RFrame = rightArrow.frame;
RFrame.origin.x -= RFrame.size.width; // move it in from the right.
rightArrow.frame = RFrame;
[UIView commitAnimations];
}
- (void) horizontalPart2 {
// --------------------------------------------
// and animate them out
// delay enough for the first one to finish
[UIView beginAnimations:#"bar" context:nil];
[UIView setAnimationDelay: 1.0f ]; // in seconds
[UIView setAnimationDuration: 3.0f ];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDidStopSelector:#selector(horizontalAnimationDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
CGRect LLFrame = leftArrow.frame;
LLFrame.origin.x -= LLFrame.size.width; // move it off to the left. // THIS IS NOT HAPPENING.
leftArrow.frame = LLFrame;
CGRect RFrame = rightArrow.frame;
RFrame.origin.x += RFrame.size.width;
rightArrow.frame = RFrame;
leftArrow.alpha = 0.0f;
rightArrow.alpha = 0.0f;
[UIView commitAnimations];
}