stop animation when button is pressed - ios

I am having the code below, which is an animation of a UIButton. But when the button is pressed, i want the animation stop at once and do something else, while if the animation continue it does something else. My problem is that even i press the button, the animation continue and it will do both step 1 and 2.
What am i missing in the code?
int frame1 = 600;
int frame2 = 100;
hit11 = [[UIButton alloc]initWithFrame:CGRectMake((arc4random() % (frame1 - frame2)+frame2),200,20,20)];
[hit11 addTarget:self action:#selector(hit:) forControlEvents:UIControlEventTouchUpInside];
[hit11 setBackgroundImage:[UIImage imageNamed:#"touchrightdown.png"] forState:UIControlStateNormal];
[self.view addSubview:hit11];
[UIView animateWithDuration:2.0 delay:0.1 options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction animations:^{
hit11.transform = CGAffineTransformMakeScale(7,7);
hit11.alpha=0.5;
} completion:^(BOOL finished) {
if (finished) {
//DO STEP 2.
hit11.hidden=YES;
}
NSLog(#"got hit");
}];
-(void) hit:(UIButton*)sender{
NSLog(#"1/10");
//DO STEP 1.
}

Try adding this:
[sender.layer removeAllAnimations];
in your hit:(UIButton*)sender method.

Related

Objective-C completion block for animation within for loop (pause loop processing)

I have a method to fade in, then fade out a button label (shown below):
-(void)fade:(NSString *)text
{
NSLog(#"Starting Fade In for symbol %#",text);
[self.symbolButton setAlpha:0.0f];
[self.symbolButton setTitle:text forState:UIControlStateNormal];
[UIView animateWithDuration:2 animations:^{
[self.symbolButton setAlpha:1.0f];
} completion:^(BOOL finished) {
NSLog(#"Starting Fade Out for symbol %#",text);
[UIView animateWithDuration:2 animations:^{
[self.symbolButton setAlpha:0.0f];
} completion:nil];
}];
}
This works as intended. However, rather than a single string, I want to cycle through the contents of an array (eg. fade-in "A", fade-out "A", fade-in "B", fade-out "B".....).
In the above code, the completion block waits for the fade-in to finish before starting the fade-out (good). However, if I try and process an array using a for loop (modify the method to accept array and nest actions in a for loop that iterates the array), the loop cycles immediately rather than waiting for first character to complete.
Is there a way to use a completion block in the second animation action to pause processing of the loop - or am I going about this in the wrong way?
You may try this. I didn't test it but the idea should work
NSArray<UIButton*>* arrButtons;
NSString* text;
for (int i = 0 ; i < arrButtons.count; i++) {
UIButton* b = arrButtons[i];
b.alpha = 0.0f;
[b setTitle:text forState:UIControlStateNormal];
[UIView animateKeyframesWithDuration:2 delay:4*i options:0 animations:^{
b.alpha = 1.0f;
} completion:^(BOOL finished) {
NSLog(#"Starting Fade Out for symbol %#",text);
[UIView animateWithDuration:2 animations:^{
b.alpha = 0.0f;
} completion:nil];
}];
}

Make a view appear and disappear in a button

I want to make a view appear out of a button (slide up and zoom) on click and then on tap again disappear in same fashion into that button. I have achieved a view coming out of a button with this code. But reverse is not working. any help
- (IBAction) arrowBtnClick{
_arrowUpBtn.enabled=false;
if (_isSliderMenuPresent) {
[UIView animateWithDuration:.5f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
_sliderView.frame = CGRectMake(_sliderView.frame.origin.x, 440.0f, _sliderView.frame.size.width, 200 );
} completion:^(BOOL finished)
{
_isSliderMenuPresent = false;
_sliderView.hidden = true;
_arrowUpBtn.enabled=true;
[_arrowUpBtn setBackgroundImage:[UIImage imageNamed:#"arrow_up.png"] forState:UIControlStateNormal];
}];
}
else{
_sliderView.hidden = false;
_sliderView.transform = CGAffineTransformMakeScale(0.00, 0.00);
[UIView animateWithDuration:.5f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
_sliderView.transform = CGAffineTransformIdentity;
_sliderView.frame = CGRectMake(_sliderView.frame.origin.x,_sliderView.frame.origin.y-150, _sliderView.frame.size.width, 200 );
} completion:^(BOOL finished)
{
_isSliderMenuPresent = true;
_arrowUpBtn.enabled=true;
[_arrowUpBtn setBackgroundImage:[UIImage imageNamed:#"close_button.png"] forState:UIControlStateNormal];
}];
}
}

Animate N-1th button to the position where other buttons removed

`
[self lastbuttonOnToThisPosition:selectedbtn.tag]
-(int)lastbutt0nToThisPosition:(int)pos
{
int p=[array count]-1;
if((pos) == ([array count]-1))
return 0;
for(p=[array count]-1;p>=0;--p)
{
UIButton *btn=(UIButton*)[self.view viewWithTag:p];
if(![btn isSelected])
{
UIButton *Remove=(UIButton*)[self.view viewWithTag:pos];
[Remove removeFromSuperview];
[btn setTag:pos];
[array replaceObjectAtIndex:pos withObject:[array objectAtIndex:p]];
[array removeObjectAtIndex:p];
return p;
}
}
return p;
}`
I have say for example N UIButtons arranged sequentially, once I select any of them it gets removed. I want to animate the N-1th button to the position where other buttons removed.
Please can anyone suggest me suitable method.
Because of you didnt provide your code, i am including a sample code. Please make changes according to your need.
If there are 3 buttons and if you are tapping second button, then our method should be
-(IBAction)tappedBtn2:(id)sender
{
[UIView animateWithDuration:0.33f
delay:0.0f
options:UIViewAnimationOptionShowHideTransitionViews
animations:^{
[btn2 removeFromSuperview];
[btn3 removeFromSuperview];
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.33f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[btn1 setFrame:CGRectMake(btn2.frame.origin.x, btn2.frame.origin.y , btn1.frame.size.width, btn1.frame.size.height)];
}
completion:nil];
}];
}
If you are using a for loop, then use the below code for obtaining the uibutton with a particular tag for deletion and animation
[(UIButton*)[self.view viewWithTag:tagId] // assuming buttons are added to self.view

Change Background Image and animate an UIButton when tapped iOS 7 [duplicate]

This question already has answers here:
Animating only the image in UIBarButtonItem
(4 answers)
Closed 8 years ago.
I have an UIButton created by the following code
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"refresh_icon.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"reload_selected.png"] forState:UIControlStateSelected];
[button addTarget:self action:#selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 20 , 20)];
Here when it's clicked the selector buttonAction is called and I am animating the button by a 360 degree rotation like this
- (void) buttonAction : (id) sender {
NSLog(#"Reload Button Clicked");
[self runSpinAnimationOnView:self.button duration:1.0 rotations:1.0 repeat:0];
}
- (void) runSpinAnimationOnView:(UIView*)view duration:(CGFloat)duration rotations:(CGFloat)rotations repeat:(float)repeat;
{
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = repeat;
[view.layer addAnimation:rotationAnimation forKey:#"rotationAnimation"];
}
It's working good but it's not that I actually want. I want that , when my button is clicked then button will take the image "reload_selected.png" (which I set for UIControlStateSelected) as background and then run the animation. When the animation is finished then button will have to return to it's actual background ("refresh_icon.png") again.
Can anyone suggest some change in code that will help me achieve the action I described above ? Thanks in advance for your help.
Can you try like this,
[UIView animateWithDuration:YOURDURATION
delay:0
options:(UIViewAnimationOptionCurveLinear)
animations:^ {
[button setImage:[UIImage imageNamed:#"reload_selected.png"] forState:UIControlStateSelected];
button.transform = CGAffineTransformRotate(CGAffineTransformIdentity,M_PI * 2);
}
completion:^(BOOL finished) {
[button setImage:[UIImage imageNamed:#"refresh_icon.png"] forState:UIControlStateNormal];
}
];
Instead of using Core Animation, you can use animateWithDuration:animations:completion: method of UIView. This method allows you to specify a completion block whick you can use to reset the image once the animation is completed.
EDIT:
Do something like
[view animateWithDuration:duration animations:^{
//Do your animations here
} completion: ^(BOOL finished){
if(finished) {
//reset the image
}
}];
To specify the animations you might want to animate the view's transform property using CGAffineTransformRotate.

How to create an animation by changing images after a certain amount of time

Hello guys I am new to xcode and I am trying to animate balloons on touch by changing its images: this is my code:
now the problem i am facing is its not animating images means the animation timer is not working: please guide me what should i do to animate the images with time: if I am not doing it properly then please guide me that how can i do it by NSTimer?
-(void)baloonbursting:(UIButton *)button withEvent:(UIEvent *)event{
if ([[UIImage imageNamed:#"redbaloons.png"] isEqual:button.currentImage]) {
NSLog(#"em redbaloons.png");
UIImage *bubbleImage3 = [UIImage imageNamed:#"redburst.png"];
[button setImage:bubbleImage3 forState:UIControlStateNormal];
}
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView animateWithDuration:1.0f animations:^(){
// define animation
if ([[UIImage imageNamed:#"redburst.png"] isEqual:button.currentImage]) {
NSLog(#"em redbaloons.png");
UIImage *bubbleImage3 = [UIImage imageNamed:#"redburst2.png"];
[button setImage:bubbleImage3 forState:UIControlStateNormal];
}
}
completion:^(BOOL finished){
// after the animation is completed call showAnimation again
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished){
if (finished) {
[button removeFromSuperview];
}}];
}];
}
I want you to give you a solution to show you the right direction to think. That is, why I developed a small test project in Xcode and I controlled that this code really works.
First: forget NSTimers for this animation!
The idea is, that you "play" around with subviews, because you can change their alpha properties from 0.0 (invisible) to 1.0 (fully opaque), which are supported by the SDK's view animations.
Please change the image names according to your own file names (I've used my own here).
The following method checks, if the button's image is that one that shall invoke an animation - exactly what you did before. If this condition is met, it visually animates the change of the button's image to another image:
- (IBAction)balloonBursting:(UIButton *)sender
{
BOOL doAnimate = NO;
UIImageView *ivOldBubbleImage;
UIImageView *ivNewBubbleImage;
if ([[UIImage imageNamed:#"BalloonYellow.png"] isEqual:sender.currentImage]) {
NSLog(#"will animate");
doAnimate = YES;
UIImage *newImage = [UIImage imageNamed:#"BalloonPurple.png"];
ivNewBubbleImage = [[UIImageView alloc] initWithImage:newImage];
ivNewBubbleImage.alpha = 0.0;
ivOldBubbleImage = sender.imageView;
[sender addSubview:ivNewBubbleImage];
}
if (doAnimate) {
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView animateWithDuration:1.0f animations:^(){
// define animation
ivOldBubbleImage.alpha = 0.0;
ivNewBubbleImage.alpha = 1.0;
}
completion:^(BOOL finished){
[sender setImage:ivNewBubbleImage.image forState:UIControlStateNormal];
[ivNewBubbleImage removeFromSuperview];
}];
}
}

Resources