I am trying to animate a UITextView to expand the to the width of its containing UIToolbar.
But it animates weird, jumping around.
Can anyone help me make understand why my textbox jumps around?
#define ANIMATION_DURATION 0.5
#define ANIMATION_DELAY 0.03
#interface WebViewController () <UITextFieldDelegate>{
CGRect URLBAR_DEFAULT;
}
-(void)viewDidLoad{
self.txtURLBar = [[UITextField alloc] init];
self.txtURLBar.bounds = CGRectMake(0, 0, 100, 30);
self.txtURLBar.delegate = self;
self.txtURLBar.backgroundColor = [UIColor lightGrayColor];
self.txtURLBar.clearButtonMode = UITextFieldViewModeWhileEditing;
URLBAR_DEFAULT = self.txtURLBar.frame; //KEEP A REFRENCE TO THE ORIGINAL SIZE
}
//START EDITING EXPAND TO FULL WIDTH
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView animateWithDuration:ANIMATION_DURATION delay:ANIMATION_DELAY options:UIViewAnimationOptionCurveLinear animations:^{
[_txtURLBar setFrame:CGRectMake(3, URLBAR_DEFAULT.origin.y, self.view.frame.size.width - 10, URLBAR_DEFAULT.size.height)];
} completion:^(BOOL finished) {
}];
}
//END EDITING SHRINK BACK TO SMALL SIZE
- (void)textFieldDidEndEditing:(UITextField *)textField {
[UIView animateWithDuration:ANIMATION_DURATION delay:ANIMATION_DELAY options:UIViewAnimationOptionCurveEaseOut animations:^{
[_txtURLBar setFrame:CGRectMake(URLBAR_DEFAULT.origin.x, URLBAR_DEFAULT.origin.y, URLBAR_DEFAULT.size.width, URLBAR_DEFAULT.size.height)];
} completion:^(BOOL finished) {
}];
}
The problem may be due to the frame being set in textFieldDidBeginEditing, textFieldDidEndEditing is different. I've done the small POC with same code of yours as below. It's working fine.
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *resizeableTextField;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//START EDITING EXPAND TO FULL WIDTH
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView animateWithDuration:0.5 delay:0.03 options:UIViewAnimationOptionCurveLinear animations:^{
self.resizeableTextField.frame = CGRectMake(CGRectGetMinX(self.resizeableTextField.frame), CGRectGetMinY(self.resizeableTextField.frame), self.resizeableTextField.frame.size.width + 40, CGRectGetHeight(self.resizeableTextField.frame));
} completion:^(BOOL finished) {
}];
}
//END EDITING SHRINK BACK TO SMALL SIZE
- (void)textFieldDidEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.5 delay:0.03 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.resizeableTextField.frame = CGRectMake(CGRectGetMinX(self.resizeableTextField.frame), CGRectGetMinY(self.resizeableTextField.frame), self.resizeableTextField.frame.size.width - 40, CGRectGetHeight(self.resizeableTextField.frame));
} completion:^(BOOL finished) {
}];
}
#end
Related
I've been banging my head over what I thought would have been an easy thing. A pulsing circle, there are several example on SO, but I'm still unable to fix one last thing.
With the code below, I do have a circle that expand and contracts fine, but during contraction, the scaling is done from the CGRect's layer frame (upper left corner). Expansion works fine, and both expansion/contraction work fine on iOS8. The problem only happens on iOS7.
I tried with setting the anchor point, translating the view while expanding ... nothing seemed to do the trick... I'm doing something wrong, I don't know what.
If anyone want to try with the code below you just need a UIViewController, a label, and a button, wired to the IBOutlets below.
That's my last - known - bug before I can submit my app to the app Store... :\
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet UIButton *button;
#property (nonatomic) BOOL isExpanded;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.isExpanded = YES;
self.label.layer.cornerRadius = self.label.frame.size.width/2;
self.label.layer.masksToBounds = YES;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
- (IBAction)ExpandOrCollapse:(id)sender {
[self.button setEnabled:NO];
CGFloat animationDuration = 0.30f; // Your duration
CGFloat animationDelay = 0.0f; // Your delay (if any)
if (self.isExpanded) {
CGAffineTransform t = CGAffineTransformMakeScale(.17f, .17f);
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
scaleAnimation.duration = animationDuration;
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0f];
scaleAnimation.toValue = [NSNumber numberWithFloat:0.17f];
[self.label.layer addAnimation:scaleAnimation forKey:#"scale"];
[UIView animateWithDuration:animationDuration
delay:animationDelay
options: UIViewAnimationOptionCurveEaseIn
animations:^{
}
completion:^(BOOL finished){
self.isExpanded = NO;
[self.label setTransform:t];
[self.button setEnabled:YES];
}];
}else{
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
scaleAnimation.duration = animationDuration;
scaleAnimation.fromValue = [NSNumber numberWithFloat:0.17f];
scaleAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[self.label.layer addAnimation:scaleAnimation forKey:#"scale"];
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
}
completion:^(BOOL finished){
[self.button setEnabled:YES];
[self.label setTransform:CGAffineTransformMakeScale(1.0, 1.0f)];
self.isExpanded = YES;
}];
}
}
#end
EDIT
for eiran, here's the code with his modifications. Problem is still present unfortunately..
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet UIButton *button;
#property (nonatomic) BOOL isExpanded;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.isExpanded = YES;
self.label.layer.cornerRadius = self.label.frame.size.width/2;
self.label.layer.masksToBounds = YES;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
- (IBAction)ExpandOrCollapse:(id)sender {
[self.button setEnabled:NO];
CGFloat animationDuration = 0.30f; // Your duration
CGFloat animationDelay = 0.0f; // Your delay (if any)
if (self.isExpanded) {
[UIView animateWithDuration:animationDuration
delay:animationDelay
options: UIViewAnimationOptionCurveEaseIn
animations:^{
[self.label setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 0.17f, 0.17f)];
}
completion:^(BOOL finished){
self.isExpanded = NO;
[self.button setEnabled:YES];
}];
}else{
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
[self.label setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f)];
}
completion:^(BOOL finished){
[self.button setEnabled:YES];
self.isExpanded = YES;
}];
}
}
This seemed to work for me:
[UIView animateWithDuration:0.75
delay:0
options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionAllowUserInteraction
animations:^{
self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.95, 0.95);
}completion:^(BOOL b){
}];
that's a repeating scale animation.
EDIT:
OK then:) apple works in mysterious ways.
i've found a solution for you, but i'm not sure what the problem is.
in ios 7.1, if you work with a storyboard, the scaling does what you say.
BUT, if you add a component dynamically, the animation works fine. add this to your code and check it out:
- (void)viewDidLoad {
[super viewDidLoad];
self.isExpanded = YES;
UIButton* b = [UIButton buttonWithType:UIButtonTypeCustom];
[b setFrame:CGRectMake(100, 400, 120, 40)];
[b addTarget:self action:#selector(expand:) forControlEvents:UIControlEventTouchUpInside];
[b setBackgroundColor:[UIColor blueColor]];
[b setTitle:#"added dynamically" forState:UIControlStateNormal];
[self.view addSubview:b];
}
-(void)expand:(UIButton*)sender{
CGFloat animationDuration = 0.30f; // Your duration
CGFloat animationDelay = 0.0f; // Your delay (if any)
if (self.isExpanded) {
[UIView animateWithDuration:animationDuration
delay:animationDelay
options: UIViewAnimationOptionCurveEaseIn
animations:^{
[sender setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 0.8f, 0.8f)];
}
completion:^(BOOL finished){
self.isExpanded = NO;
}];
}else{
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
[sender setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f)];
}
completion:^(BOOL finished){
self.isExpanded = YES;
}];
}
}
as you said, it was fixed on ios 8.
i thought it might have something to do with constraints, but it looks like it doesn't.
added a project that demonstrates this test here:
the test
hope that helps, eiran.
Currently I am creating an App when you first launch it, there is some Introduction Text and 2 Buttons. 1 Button to skip the Tutorial and the other one to do the Tutorial. I want that these 2 Buttons and those Labels appear after a certain Time and with an Fade In animation. Could anyone give me some code examples? I already tried searching but the results weren't helpful for me.
I Updatet some Code. Now looks like this:
.h File:
#interface startViewController : UIViewController {
IBOutlet UIButton *notourb;
IBOutlet UIButton *tourb;
IBOutlet UILabel *welcomeLabel;
}
- (void)shownotourb;
- (void)showtourb;
- (void)showwLabel;
And the .m File (I will only show the code from the buttons because I figured out how to do the Labels in another way):
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(shownotourb) withObject:nil afterDelay:2.0];
[self performSelector:#selector(showtourb) withObject:nil afterDelay:2.5];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)shownotourb {
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
[self.view addSubview:notourb];
}
completion:^(BOOL finished){}];
}
- (void)showtourb {
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
[self.view addSubview:tourb];
}
completion:^(BOOL finished){}];
}
create a method which will add the buttons to the view, and use the performSelector:afterDelay method to add them like this:
in your viewDidLoad:
[self performSelector:#selector(addButtonsToView) withObject:nil afterDelay:5.0];
and add this method to add your buttons:
-(void)addButtonsToView
{
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
[self.view addSubview:button1];
[self.view addSubview:button2];
}
completion:^(BOOL finished){}];
}
hope it helps :)
I need to move an UIImageView from x,y to x,y1.
This is what i have. I tried lots of different codes in -(void)animation, most using animateWithDuration but none seems to work. It just doesn't do anything. I must be missing something. Is .h correct? How would you make the image move? I then have to loop that, how can i do that? It's my first time with animate, I can't figure out what to do, it has to be simple. Thanks in Advance.
in .h I connected it this way
#import <UIKit/UIKit.h>
#interface ImageBeaconViewController : UIViewController {
__weak IBOutlet UIImageView *blueView;
}
#end
the in .m I've got
- (void)viewDidLoad
{
[self animation];
[super viewDidLoad];
}
....
- (void)animation{
[UIView animateWithDuration:3 animations:^{
blueView.alpha = 1;
blueView.center = CGPointMake(blueView.center.x , blueView.center.y +??);
}];
}
??= I still have to decide how much I want it to move
This way the app crashes as soon as I get to the screen with the animation
Add Method Like This:
- (void) animateToPoint:(CGPoint)point {
[UIView animateWithDuration:3 animations:^{
blueView.alpha = 1;
blueView.center = point;
}];
}
Call like this:
- (void) viewDidAppear:(BOOL)animated {
int distanceToSlide = 40; // will slide down 40px (use -40 to go up)
CGPoint targetPoint = CGPointMake(blueView.center.x, blueView.center.y + distanceToSlide);
[self animateToPoint:targetPoint];
}
NOTE
Notice that I put your animation call in viewDidAppear if you animate in viewDidLoad you won't see anything because your view isn't displayed yet.
If it's still not moving, make sure "useAutolayout" is not selected check this:
Just because I already built it, try this for tap to animate:
In your viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]init];
tap.numberOfTapsRequired = 1;
[tap addTarget:self action:#selector(handleTap:)];
[self.view addGestureRecognizer:tap];
}
Then, use these:
- (void) handleTap:(UITapGestureRecognizer *)tap {
int distanceToSlide = 40; // will slide down 40px (use -40 to go up)
CGPoint targetPoint = CGPointMake(blueView.center.x, blueView.center.y + distanceToSlide);
[self animateToPoint:targetPoint];
}
- (void) animateToPoint:(CGPoint)point {
[UIView animateWithDuration:3 animations:^{
blueView.alpha = 1;
blueView.center = point;
}];
}
Here's a way to loop it:
#implementation ImageBeaconViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
pointA = CGPointMake(40, 40);
pointB = CGPointMake(250, 350);
blueView.center = pointA;
}
- (void) viewDidAppear:(BOOL)animated {
[self animate];
}
- (void) animate {
if (CGPointEqualToPoint(_blueView.center, pointA)) {
[self animateToPoint:pointB];
}
else {
[self animateToPoint:pointA];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) animateToPoint:(CGPoint)point {
[UIView animateWithDuration:1.0 animations:^{
_blueView.alpha = 1;
_blueView.center = point;
} completion:^(BOOL finished) {
if (finished) {
[self animate];
}
}];
}
#end
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
blueView.alpha = 1;
blueView.center = CGPointMake(blueView.center.x , blueView.center.y + 100);
} completion:^(BOOL finished) {
//if you need any thing after animation is done
}];
this is them code for animation i have
EDITED:
I had created a slide in menu for my view and it works as i wanted, this was the original guide that I used.
http://www.youtube.com/watch?v=79ZQDzzOHLk
My goal was to get this programmed once in a class and get it to work on any view controller that i decided to call it in.
Thanks to #harsh.prasad and some additional research I have managed to get this to work to a point where it works as I want apart apart from linking buttons on to it.
So to update this question in the hope it may help someone else.
This is what I did:
I created a UIView class and called it MenuOne.
MenuOne.h
#import <UIKit/UIKit.h>
#interface TFMenuOne : UIView {
// Pop Up Menu
IBOutlet UIScrollView *scrollView;
IBOutlet UIButton *openMenu;
int draw1;
IBOutlet UIButton *backButton;
}
// Pop Up Menu
- (IBAction)openMenu_clicked:(id)sender;
// Reset draw1 to 0
- (void) resetView: (id) sender;
#property (retain, nonatomic) IBOutlet UIScrollView *scrollView;
#end
MenuOne.m
#import "TFMenuOne.h"
#implementation TFMenuOne
#synthesize scrollView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
draw1 = 0;
scrollView = [[UIScrollView alloc] init];
[scrollView setBackgroundColor:[UIColor whiteColor]];
[scrollView setFrame:CGRectMake(0, 315, 568, 5)];
[scrollView setContentSize:CGSizeMake(568, 5)];
backButton = [[UIButton alloc] init];
[backButton setBackgroundColor:[UIColor greenColor]];
backButton.frame = CGRectMake(224, 350, 120, 30);
openMenu = [[UIButton alloc] init];
[openMenu setBackgroundImage:[UIImage imageNamed:#"menu-button-#2.png"]
forState:UIControlStateNormal];
openMenu.adjustsImageWhenHighlighted = NO;
[openMenu addTarget:self
action:#selector(openMenu_clicked:)
forControlEvents:UIControlEventTouchUpInside];
openMenu.frame = CGRectMake(256, 269, 64, 46);
[self addSubview:scrollView];
[self addSubview:backButton];
[self addSubview:openMenu];
}
return self;
}
// Allow for touch even through transparent View class
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *view in self.subviews) {
if (!view.hidden && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
return YES;
}
return NO;
}
- (void) resetView: (id) sender {
draw1 = 1;
[self openMenu_clicked:sender];
}
- (IBAction)openMenu_clicked:(id)sender {
if (draw1 == 0) {
draw1 = 1;
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
scrollView.frame = CGRectMake(0, 260, 568, 60);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
openMenu.frame = CGRectMake(256, 214, 64, 46);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
backButton.frame = CGRectMake(224, 275, 120, 30);
} completion:^(BOOL finished) {
}];
} else {
draw1 = 0;
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
scrollView.frame = CGRectMake(0, 315, 568, 5);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
openMenu.frame = CGRectMake(256, 269, 64, 46);
} completion:^(BOOL finished) {
}];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
backButton.frame = CGRectMake(224, 350, 120, 30);
} completion:^(BOOL finished) {
}];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
After a lot of trial and error, in order to get this UIView class to appear on multiple ViewControllers I call the view like this in the m file of the view controller. The obstacles I ran in to was that the menu would open but when I left the view controller to go to another view controller the menu would be in the state it was in when i left, it wouldn't reset back to closed. The code below covered that thanks again to #harsh.prasad. I also managed to get the menu to animate in.
#interface TFMapViewController ()
{
TFMenuOne *menuView;
}
#end
#implementation TFMapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
[menuView resetView:nil];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
menuView = [[TFMenuOne alloc] initWithFrame:CGRectMake(0, 51, 568, 320)];
[self.view addSubview:menuView];
}
- (void) viewDidAppear:(BOOL)animated
{
[UIView animateWithDuration:0.5 delay:0.5 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
menuView.frame = CGRectMake(0, 0, 568, 320);
} completion:^(BOOL finished) {
}];
}
- (void) viewDidDisappear:(BOOL)animated
{
[menuView resetView:nil];
[UIView animateWithDuration:0.0 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
menuView.frame = CGRectMake(0, 51, 568, 320);
} completion:^(BOOL finished) {
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// Allows for Exit button to work
- (IBAction)returned:(UIStoryboardSegue *)segue {
}
#end
I you want you can use tabsController if that kind of feature you want, otherwise create a class of your slide in menu view and then you can use it in all of your views as you like. No same piece of code is to be rewritten.
EDIT:
Suppose you have created a class CustomMenuView which basically creates your menu view. So now you can use this in every view controller you want to use it in in the following way:
CustomMenuView *menuView = [CustomMenuView alloc] initWithFrame:CGRectMake(0, 200, 320, 100);
menuView.<properties you want to pass> = <set properties here>;
[self.view addSubView:menuView];
This will set the view with the custom menu and then you can handle the actions in this menu.
1)Here is an old tutorial for creating menu - http://www.raywenderlich.com/32054/how-to-create-a-slide-out-navigation-like-facebook-and-path/projectlayout
2)A better way is to create Drawer menu With container views. You can read more about container views from WWDC videos.
3)Or if you are lazy to d it yourself, try this library http://cocoacontrols.com/platforms/ios/controls/jtrevealsidebar
P.S. No , you do not havev to repeat the code.
You can try this,
First make a view on the origin point x = 0 y = 480 (for iphone4) and then run this code.
CGRect theFrame = self.viewMenuShare.frame;
theFrame.origin = CGPointMake(0, 480);
self.viewMenuShare.frame = theFrame;
theFrame.origin = CGPointMake(0,480 - 187);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f];
self.viewMenuShare.frame = theFrame;
[UIView commitAnimations];
Trying to get to grips with Xcode and seem to be making some progress over the last few weeks.
Does anyone know a way that a custom button can do a different set of animations on a second click.
So let say I have a custom button and its of Mario, when i click it he runs from the middle of the screen and out of the right hand side of the screen and then runs back in to the middle from the left of the screen, he also makes noise.
I have achieved this using this code:
- (IBAction)marioRunning_clicked:(id)sender
{
[UIView animateWithDuration:1.50 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
marioRunning.center = CGPointMake(350.5, 456.0);
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:0.00 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
marioRunning.center = CGPointMake(-30.5, 456.0);
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:1.50 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
marioRunning.center = CGPointMake(160.0, 456.0);
} completion:^(BOOL finished) {
if(finished) // NSLog ( #"Finished !!!!!" );
marioRunning.center = CGPointMake(160.0, 456.0);
}];
}
}];
}
}];
marioRunning.imageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"mario-running2"],[UIImage imageNamed:#"mario-running3"],nil];
marioRunning.imageView.animationDuration = 0.15;
marioRunning.imageView.animationRepeatCount = 19;
[marioRunning.imageView startAnimating];
}
How could I make him do a second set of animations on the next click? For example instead of running from left to right, if i tap him the second time he will Jump up and down?
Use the selected state of the button to decide which animation to do
-(void)buttonClicked:(UIButton*)button
{
if(button.selected)
{
[self doAnimation1];
}
else
{
[self doAnimation2];
}
button.selected = !button.selected;
}
This might be overkill, but here's a cool way to do what you want:
Make a subclass of UIButton, and let's call it DDDMarioButton:
typedef void (^DDDAnimationBlock)(UIButton *button);
#interface DDDMarioButton : UIButton
- (void)addAnimationBlockToQueue:(DDDAnimationBlock)block;
#end
Then in DDDMarioButton.m:
#interface DDDMarioButton ()
#property (nonatomic, strong) NSMutableArray *animationQueue;
#end
#implementation DDDMarioButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)buttonPressed:(id)button
{
DDDAnimationBlock block = self.animationQueue[0];
block(self);
[self.animationQueue removeObjectAtIndex:0];
}
- (void)addAnimationBlockToQueue:(DDDAnimationBlock)block
{
if(!self.animationQueue)
{
self.animationQueue = [NSMutableArray new];
}
[self.animationQueue addObject:block];
}
#end
and then wherever you create your buttons, you add each step one by one:
DDDMarioButton *button = [[DDDMarioButton alloc] initWithFrame:CGRectZero];
[button addAnimationBlockToQueue:^(UIButton *button) {
// perform some animation
}];
[button addAnimationBlockToQueue:^(UIButton *button) {
// perform another animation
}];
And that should do it. I haven't tested this, you'll probably need some configuration, but that's pretty much the idea.