Button fires on double not single click - xcode

I got view animations to work perfectly in Xcode (slide off the screen on a button click with CGRect.) Unfortunately I have to click the button twice to execute the animation. What have I done wrong? I appreciate any feedback
Here's my .H code
#interface AnimationBlocksViewController : UIViewController{
IBOutlet UIView *theview;
IBOutlet UIView *theview2;
BOOL isAnimated;
BOOL switchback;
}
-(IBAction)animate:(id)sender;
-(IBAction)change:(id)sender;
Here's my .M code
-(IBAction)animate:(id)sender;{
if (isAnimated) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[theview setFrame:CGRectMake(0, 0, 320, 460)];
[theview2 setFrame:CGRectMake(320, 0, 320, 460)];
[UIView commitAnimations];
isAnimated=NO;
}
else{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[theview setFrame:CGRectMake(-320, 0, 320, 460)];
[theview2 setFrame:CGRectMake(0, 0, 320, 460)];
[UIView commitAnimations];
isAnimated=YES;
}
}
-(IBAction)change:(id)sender;{
if (switchback) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[theview2 setFrame:CGRectMake(0, 0, 320, 460)];
[UIView commitAnimations];
switchback=NO;
}
else{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.5];
[theview2 setFrame:CGRectMake(320, 0, 320, 460)];
[theview setFrame:CGRectMake(0, 0, 320, 460)];
[UIView commitAnimations];
switchback=YES;
}
}
It works but I have to double click to trigger the animation, what have I done wrong?
Thank you

After your initial double click, does a subsequent single click trigger the animation properly? If so, it may be that you haven't explicitly initialised your BOOL variables, though they should default to NO. Try doing that and see if it helps.
If you always need to do two taps to animate, maybe try inserting a call to the run loop to see if it's only processing the animation after running on your application thread for a while i.e. it could be that only when it comes to process a second click event does it actually go and fetch any pending animations and execute them. The code for that would be (after you set isAnimated and call commitAnimations):
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate date]];
Not sure whether you can just use nil for a date but try that too if you like.

Related

UIImageview Fade

I am trying to get my image to fade out and fade in with when i click on my button. Is there something wrong with this code? My image stays visible when I click on my button.
- (IBAction)Alpha:(id)sender {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:2];
_image.alpha = 1;
[UIView commitAnimations];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
}
-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
_image.alpha = 0;
[UIView commitAnimations];
}
You are calling the methods on UIVIew, the class, not on your instance of the UIImageView that you want to fade.
You'll want something like
[self.myImageView beginAnimations....

How do I loop UIAnimation?

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

Moving text up, when editing it

a view in my app roughly looks like this:
An UIImage, and beyond this, a TextView describing the image. - The text should be editable.
And now this is my question: When the user taps into the textfield, the appearend keyboard "lies over the text" (the user can't see, what he is writing).
Is there an easy to implement possibility (I'm a newbie to XCode) to swith the text to the upper part of the page, while editing it (something like: "if keyboard appers replace image by text", "if keyboard dissapears undo"),
such that the user can see the changes?
Thanks for your help,
Max
Firstly conform u are using Text Field or Text View, i m considering that u are using text Field
// #define kOFFSET_FOR_KEYBOARD 110.0 define this in the .m file and set its value accordingly
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if(self.view.frame.origin.y >= 0)
[self setViewMoveUp:YES];
}
}
-(void)setViewMoveUp:(BOOL)moveUp{
CGRect rect = self.view.frame;
if(moveUp)
{
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
}
do like this.When the delegate method called (i.e in did beginEditing method)
Write this code
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
[self.view setFrame:CGRectMake(0,-20,320,400)];
[UIView commitAnimations];
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
txtField.frame = CGRectMake(txtField.frame.origin.x, (txtField.frame.origin.y), txtField.frame.size.width,txtField.frame.size.height);
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
UIInterfaceOrientation des=self.interfaceOrientation;
if (des==UIInterfaceOrientationLandscapeLeft||des==UIInterfaceOrientationLandscapeRight)
{
txtField.frame=CGRectMake(500,250,97,37);
}
[UIView commitAnimations];
}
}
" Don't forget to given this in Vied DidLoad"
self.view.frame=[[UIScreen mainScreen]applicationFrame];
view.autoresizesSubviews=NO;
txtField.delegate=self;

UIImageView animated rotation

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>

animated UIButtons are clickable at destination before they reach destination

I have a UIView that contains a couple UIButtons that I am animating from offscreen to onscreen. I find that the region where they are heading is clickable before they reach it. The animation is pretty simple, so I'm wondering if there is something obvious that I am missing in terms of telling the code to not treat the button as if it is at the final destination (I'm not sure if that is supposed to be the expected behavior and the animation is purely a visual while the clickable region is instantaneously at the destination; I wouldn't expect it to be).
Here is the code I use to animate it. It's basically switching out a sub panel and bringing back a main panel with buttons:
// switch back to main abilities panel
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: kFadeInTime];
CGRect rect = CGRectMake(
480.0f,
mAbilities.mSubPanel.frame.origin.y,
mAbilities.mSubPanel.frame.size.width,
mAbilities.mSubPanel.frame.size.height);
mAbilities.mSubPanel.frame = rect;
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: kFadeInTime];
[UIView setAnimationDelay: kFadeInTime];
rect = CGRectMake(
kAbilitiesBorderX,
mAbilities.mPanel.frame.origin.y,
mAbilities.mPanel.frame.size.width,
mAbilities.mPanel.frame.size.height);
mAbilities.mPanel.frame = rect;
[UIView commitAnimations];
As a workaround you can disable user interaction with your panel before animations and reenable it when animation finishes:
// Animation compete handler
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
mAbilities.mSubPanel.userInteractionEnabled = YES;
}
// Animating panel
mAbilities.mSubPanel.userInteractionEnabled = NO;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: kFadeInTime];
[UIView setAnimationDelegate: self];
CGRect rect = CGRectMake(
480.0f,
mAbilities.mSubPanel.frame.origin.y,
mAbilities.mSubPanel.frame.size.width,
mAbilities.mSubPanel.frame.size.height);
mAbilities.mSubPanel.frame = rect;
[UIView commitAnimations];
If you're targeting iOS4 you can (and as specs say should) use block-based animation api:
[UIView animateWithDuration:5.0f delay:0.0f options:UIViewAnimationOptionLayoutSubviews
animations:^(void){
CGRect rect = CGRectMake(
480.0f,
mAbilities.mSubPanel.frame.origin.y,
mAbilities.mSubPanel.frame.size.width,
mAbilities.mSubPanel.frame.size.height);
mAbilities.mSubPanel.frame = rect;
}
completion:NULL
];
While animating using blocks user interaction is disabled by default - you can enable it by setting UIViewAnimationOptionAllowUserInteraction flag in options parameter:
... options:UIViewAnimationOptionLayoutSubviews | UIViewAnimationOptionAllowUserInteraction ...

Resources