UIView animation being called twice, canceling out the animation - ios

I have a UIView animation bringing a UIView from the left onto the screen, the method is being triggered so quickly in rapid succession from the bar code scanning engine that the method is being triggered then triggered again so it goes back off of the screen.
-(IBAction)showDetailModeView
{
if (detailModeViewON==FALSE)
{
[UIView beginAnimations:#"move buttons" context:nil];
[UIView setAnimationDuration:.3];
[detailModeView setFrame:CGRectMake(0, 0, 320, 568)];
[UIView commitAnimations];
detailModeViewON=TRUE;
}
else
{
[UIView beginAnimations:#"move buttons" context:nil];
[UIView setAnimationDuration:.3];
[detailModeView setFrame:CGRectMake(-320, 0, 320, 568)];
[UIView commitAnimations];
[self stopScanning];
scannedONCE = FALSE;
detailModeViewON=FALSE;
}
[self.view endEditing:YES];
}
is there some way I can basically say if this method was called within the last 5 seconds, don't do anything.
pseudo code
-(IBAction)showDetailModeView
{
if(UIVIEW animation was triggered longer than 5 seconds ago)
{
if (detailModeViewON==FALSE)
{
[UIView beginAnimations:#"move buttons" context:nil];
[UIView setAnimationDuration:.3];
[detailModeView setFrame:CGRectMake(0, 0, 320, 568)];
[UIView commitAnimations];
detailModeViewON=TRUE;
}
else
{
[UIView beginAnimations:#"move buttons" context:nil];
[UIView setAnimationDuration:.3];
[detailModeView setFrame:CGRectMake(-320, 0, 320, 568)];
[UIView commitAnimations];
[self stopScanning];
scannedONCE = FALSE;
detailModeViewON=FALSE;
}
[self.view endEditing:YES];
}
}

Edited to add that you should be using block based animations such as;
[UIView animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion];
You can find a lot of examples of this around here.
A lot of the time you need to disallow a transition while one is happening. set the gesture.enabled to NO, for example, and back to YES in the animation's completion block, or use a boolean that you set to NO before the animation begins and set it back to YES in the completion block. Then have a check to see what that boolean is before calling the animation.
These kinds of things are very common in UI implementation. Otherwise you can end up with a lot of multiple firings like you are experiencing.

Related

Moving UIImageView frame programmatically

I have UIView, in top of it i have an UIImageView, in bottom UICollectionView. My point is, when user swipe finger up, UIImageView frame should gently move out (disappear), and when user swipe down, it should again appear (with moving animation).
Actually, it worked until i set image to UIImageView. Old code (presented below) did it work just fine:
-(void)handleSwipeDown:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
self.myCollectionView.frame = CGRectMake(0, 152, 320, 480);
[UIView commitAnimations];
}
And then:
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
self.myCollectionView.frame=CGRectMake(0, 0, 320, 480);
[UIView commitAnimations];
}
After i set image:
UIImage *firstImage = [UIImage imageNamed:#"ipd1.jpg"];
self.imageSlideshow.image = firstImage;
Code above stop work. UIImage frame stay in same place.
How could i make it move ?
Any advice would be appreciated, thanks!
You should stop using the beginAnimations:context: and commitAnimations block. From Apple's documentation:
Use of this method is discouraged in iOS 4.0 and later. You should use the block-based animation methods to specify your animations instead.
Use this instead:
[UIView animateWithDuration:0.5 animations:^{
self.myCollectionView.frame = CGRectMake(0, 152, 320, 480);
}];
Just replace your entire swipeDown method with the above.

Animation does not seem to work - move view from one position to another on [self dismissViewController

I have a view currently on the screen and I would like to move it off the screen during an animation. Its current position is: CGRectMake(0, 168, 320, 50); and I would like to move it to y postion 218.
Here is my code:
[UIView beginAnimations:Nil context:NULL];
[UIView setAnimationDuration:0.3];
self.optionsView.frame = CGRectMake(0, 218, 320, 50);
[UIView commitAnimations];
Thanks in advance. Nothing is happening, the view isnt moving off screen.
Edit: When the app launches the view is off screen, i then call:
[UIView beginAnimations:Nil context:NULL];
[UIView setAnimationDuration:0.3];
self.optionsView.frame = CGRectMake(0, 168, 320, 50);
[UIView commitAnimations];
to bring the view into the main view. The problem I have is making the view go back off screen again with:
[UIView beginAnimations:Nil context:NULL];
[UIView setAnimationDuration:0.3];
self.optionsView.frame = CGRectMake(0, 218, 320, 50);
[UIView commitAnimations];
It must be noted that in order to get the view to be off screen on app launch I call:
-(void) viewDidLayoutSubviews{
self.optionsView.frame = CGRectMake(0, 218, 320, 50);
}
Update: I am also using the camera, i think dismissing the camera is affecting the layouts
I've animated the position of views as follows:
// 'frame' variable previously declared
// 'completion' block previously declared
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[_someView setFrame:frame];
}
completion:^(BOOL finished){
if (completion) {
completion();
}
}];
Have you tried it that way?
As Martin Koles has said, the block-based approach to view animation is preferred. The following is in the reference doc for UIView:
Use of the methods in this section is discouraged in iOS 4 and later.
Use the block-based animation methods instead.
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html
Use block instead:
[UIView transitionWithView:self.view duration:0.3 options:UIViewAnimationOptionCurveEaseInOut animations:^{
// final view elements attributes goes here
} completion:nil];
This is the modern way of doing animations. You can even specify a completion block, something that should happed after the animation is done, if needed.
Try using this
[UIView animateWithDuration:0.3 delay:0 options: UIViewAnimationOptionCurveLinear
animations:^{
self.optionsView.frame = CGRectMake(0, 218, 320, 50);
} completion:nil];
Worked fine with me.
Make sure the view is connected in the xib to its proper object.

How do I animate my subviews on adding them?

I have developed a font selection that utilizes UIPickerView and UIToolbar, which are both added on touching a UIButton.
But they just kind of pop in which looks sloppy.
is there a way to animate them?
here is the method that adds them (it's called on clicking the button) :
-(void)showPicker
{
[self.view addSubview:_fontPicker];
[self.view addSubview:pickerTB];
}
You can animate them in a couple of ways, but probably the easiest is to just fade them in.
Fade In
[someView setAlpha:0]
[self.view addSubview:someView];
[UIView beginAnimations:#"FadeIn" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
[someView setAlpha:1];
[UIView commitAnimations];
Fade Out
float fadeDuration = 0.5;
[UIView beginAnimations:#"FadeOut" context:nil];
[UIView setAnimationDuration:fadeDuration ];
[UIView setAnimationBeginsFromCurrentState:YES];
[someView setAlpha:0];
[UIView setAnimationDidStopSelector:#selector(removeView)];
[UIView commitAnimations];
-(void) removeView {
[someView removeFromSuperview];
}
Something as simple as that.
Depends on what type of animation you want to use. For example, this would look like dissolve.
Anyways look into UIView animateWithDuration...
pickerTB.alpha = _fontPicker.alpha = 0;
[self.view addSubview:_fontPicker];
[self.view addSubview:pickerTB];
[UIView animateWithDuration:1 animations:^{_fontPicker.alpha = 1; pickerTB.alpha = 1}];
You could use transforms or change frame origins to make the views fly in from positions outside the screen too. In that case, inside the animations block, specify the new on screen position. You can do this in two ways, change the frame with an updated origin or apply a CGAffineTransformMakeTranslation(dx,dy)
You need to add the subview with a frame value that is where you want the animation to begin from (off-screen?) then change the frame value inside your animation block. The frame will change over the duration, causing the appearance of movement. The view must already be a subview - I don't believe adding a subview is something you can animate, it makes no sense.
-(void) showPicker{
[self.view addSubview: _fontPicker];
_fontPicker.frame = CGRectMake(0, 0, 120, 40);// somewhere offscreen, in the direction you want it to appear from
[UIView animateWithDuration:10.0
animations:^{
geopointView.frame = // its final location
}];
}
Initially set your picker view frame and tool bar frame like this one..
-(void)viewDidLoad
{
[super viewDidLoad];
pickerTB.frame = CGRectMake(0,568,320,44);
fontPicker.frame = CGRectMake(0, 568, 320, 216);
}
-(void)showPicker
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.30];
if(isiPhone5)
{
pickerTB.frame = CGRectMake(0,288,320,44);
fontPicker.frame = CGRectMake(0, 332, 320, 216);
}else{
pickerTB.frame = CGRectMake(0,200,320,44);
fontPicker.frame = CGRectMake(0,244, 320, 216);
}
[UIView commitAnimations];
}

how to move view upside while entering any text in input field

I have app i want that when user enters any data then view should slide up.
I am writing this code this code works fine in another app but not working in this app.I am following same way.
-(void)showAnimationBack{
NSLog(#"Back Animation is Working");
[UIView animateWithDuration:0.5
animations:^{
self.subViewLand.frame = CGRectMake(0,-10,1024,768);
}];
}
-(void) showAnimationPests{
NSLog(#" Animation is Working");
[UIView animateWithDuration:0.5
animations:^{
self.subViewLand.frame = CGRectMake(0,-200,1024,768);
}];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
self.subViewLand.frame = CGRectMake(0,-200,1024,768); // or to self.view.frame = CGRectMake(0,-200,1024,768);
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
self.subViewLand.frame = CGRectMake(0,-200,1024,768); // or to self.view.frame = CGRectMake(0,-200,1024,768);
[UIView commitAnimations];
}
This code will work
in textfielddidBeginEditing Method set view frame like this
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self.subViewLand setFrame:CGRectMake(0, -200, 320, 480)];
}
in textfielddidEndEditing Method set view frame as it is.
- (void)textFieldDidEndEditing:(UITextField *)textField{
[self.subViewLand setFrame:CGRectMake(0, 0, 320, 480)];
}
It will definitely work. :)
In textFieldDidBeginEditing() call the your method showAnimationPests() and similarly in textFieldDidEndEditing() call showAnimationBack() .
This will work fine for you.

scroll view set animation duration

I have a scrollView with some text fields. when the keyboard show, the scroll view goes. When the keyboard is hidden the scroll view goes down. It works correctly. The only thing is that the keyboard takes 0.5 seconds to come up, so during that time I can see the white background. I would like to set a duration to my scroll3 to 0.5.
-(void)textFieldDidBeginEditing: (UITextField *)textField {
NSLog(#"sowing keyboard");
scroll3.frame = CGRectMake(0, -200, 768, 960);
[scroll3 scrollRectToVisible:scroll3.frame animated:YES];
}
-(void)textFieldDidEndEditing: (UITextField *)textField{
NSLog(#"hiding keyboard");
scroll3.frame = CGRectMake(0, 44, 768, 960);
}
How can I?? I tried [scroll3 setAnimationDuration: 0.5]; but it does not work!!! Help ME Please!!! Thanks a lot.
May be this -
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[scroll3 setFrame:CGRectMake(0, -200, 768, 960)];
[UIView commitAnimations];
}
-(void)textFieldDidEndEditing: (UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[scroll3 setFrame:CGRectMake(0, 44, 768, 960)];
[UIView commitAnimations];
}
Since the UIScrollView manages its own animation you could try to set the decelerationRate to something higher so that the animation takes longer. I know that works for manual swipes, but I'm not sure if that also goes for automated swipes (when you set the visible rect). It's worth a try.
If it is possible in your case you might just use an NSTimer.
This way you would not really change the duration of the animation but delay it a little bit
so that the background is not visible while the keyboard shows/hides.
This might look similar to the following code:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2] target:self
selector:#SEL(scrollMyScrollView) userInfo:nil repeats:NO];
This will call the given method after 0.2 seconds.
In the "scrollMyScrollView"-Method you do just what you do now.
Hope that helps ;)

Resources