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.
Related
I have set the animation like seen in below image. In which UIbutton move from left to right and then top to bottom. Animation work correctly but after completion of animation UIButton comes to its original place before the segue perform. so, it's not look good. I want to set that after the completion of animation UIButton can't come to it's own place before segue .
Here is my try with Image.
//Move button Left to Right
- (IBAction)btnEasy:(id)sender {
Easy=YES;
NSLog(#"your x is: %f ", self.btnEasy.frame.origin.x);
NSLog(#"your y is: %f ", self.btnEasy.frame.origin.y);
x1=self.btnEasy.frame.origin.x;
y1=self.btnEasy.frame.origin.y;
CGRect screenRect = [[UIScreen mainScreen] bounds];
[UIView animateWithDuration:1.150 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.btnEasy.frame = CGRectMake(screenRect.size.width/1.80, self.btnEasy.frame.origin.y, self.btnEasy.frame.size.width, self.btnEasy.frame.size.height);
[self performSelector:#selector(btneasyanimation) withObject:self afterDelay:1.160 ];}
completion:^(BOOL finished) {
}];
//Move Button top to Bottom
if (Easy==YES) {
if (isiPad2 || isiPadAir || isiPadRatina) {
//[self.view layoutIfNeeded];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:1.0];
[_btnEasy setFrame:CGRectMake(self.view.frame.origin.x+290, self.view.frame.origin.y+900, self.btnEasy.frame.size.width, self.btnEasy.frame.size.height)];
[UIView commitAnimations];
}
else if (isiPhone4s) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:1.0];
[_btnEasy setFrame:CGRectMake(self.view.frame.origin.x+92, self.view.frame.origin.y+428, self.btnEasy.frame.size.width, self.btnEasy.frame.size.height)];
[UIView commitAnimations];
}
}
[self performSelector:#selector(segueeMethod) withObject:self afterDelay:1.160 ];
Image :-
If you are not placing directly the button given it the frame, thus using autolayout (autoresize will end with the same effect). You need to explicitly use autolayout, retain a reference to your constraints and update them (you can search here how to do that) and then set the UIView animation block [button layoutIfNeeded]
You can see a detailed answer about it in this answer
There is an easy and quick way that will work with your current implementation. Provided you know exactly where you want the view to be once the animation is done, you can do the following:
in UIView animateWithDuration: ... assign the final transform (position & orientation) of the view in the completion block, i.e.:
completion:^(BOOL finished) {
// Assign views transform and appearance here, for when the animation completes
}
Hope that helps.
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.
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.
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];
}
My program has a UIToolBar which contains a UITextField and a UIButton. The whole view (self.view) goes when the soft keypad comes up. As the UIToolBar is moved to a new position, the button sometimes doesn't capture events properly. Several clicks on the button is required to fire a single event.
The following set of code is executed when the keyboard comes up
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
self.view.frame = CGRectMake(0,-220,320,400);
tableView.frame = CGRectMake(10, 220, 320, 264);
[UIView commitAnimations];
Try this
[UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
self.view.frame = CGRectMake(0,-220,320,400);
tableView.frame = CGRectMake(10, 220, 320, 264);
}completion:^(BOOL finished) {}];