I'm using UIScrollView and using scrollRectToVisible:animated
This is working fine for me.
But I want to scroll to a location slowly so that user can notice the effect.
Is it possible.
I'm trying the following code, but didn't succeed.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:2.0];
[scrlView scrollRectToVisible:<<some cgrect>> animated:YES];
[UIView commitAnimations];
The solution is actually pretty easy. If you use [scrollView scrollRectToVisible:frame animated:YES] the scrollview will start it's own animation, so in order to animate with your duration you have to use [scrollView scrollRectToVisible:frame animated:NO] within your animation.
In other words: This will work.
[UIView animateWithDuration:3
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{ [scrollView scrollRectToVisible:frame animated:NO]; }
completion:NULL];
Related
I am developing an iPhone application, where i need to move a first view controller slowly upward in animation and move to second view controller. I am thinking to use CoreAnimation for moving the first view controller slowly upward and push to next view controller. Could someone help on giving what are the classes/apis available to achieve this?
Thank you!
Try this,
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:yourfirstview cache:YES];
[UIView setAnimationDidStopSelector:#selector(remove_view)];
//change frame here
yourfirstview.frame =CGRectMake(0,-480,320,480);
[UIView commitAnimations];
-(void)remove_view
{
[yourfirstview removeFromSuperview];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:yoursecondview cache:YES];
//change frame here
yoursecondview.frame =CGRectMake(0,0,320,480);
[UIView commitAnimations];
}
You can easily achieve this on a single view controller using multiple UIViews
As per Apple's documentation:
In iOS 4 and later, use the block-based animation methods.
So, in order to produce the intended results, using the following code.
UIView *mySecondView = [[UIView alloc] initWithFrame:CGRectMake(0, 480, 320, 480)];
[mySecondView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:mySecondView];
[UIView animateWithDuration:2.0 delay:3.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[mySecondView setTransform:CGAffineTransformMakeTranslation(0, -480)];
}completion:^(BOOL done){
}];
I am using such code to present a new view, I don't it's good or not. Currently the default animation is show the view from bottom up, but i want it to animate from right to left(fly in), is it possible to change the default animation type and how? Thanks.
[self presentModalViewController:navController animated:animated];
You can disable the slide-up animation like this:
[self presentModalViewController:navController animated:NO];
Then you can provide your own animation code:
navController.view.frame = CGRectMake(320, 0, navController.view.frame.size.width, navController.view.frame.size.height);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
navController.view.frame = CGRectMake(0, 0, navController.view.frame.size.width, navController.view.frame.size.height);
[UIView commitAnimations];
This example gives you the "Fly-in" from right with a smooth speed-curve.
Another way is using the built in slide-in from right with navigationcontroller:
[self.navigationController pushViewController:navController animated:YES];
In this one, your top-viewcontroller needs to be a UINavigationController and it's rootcontroller needs to be your viewcontroller. Then you can push other viewcontrollers.
I have done this and its working for me try ths:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.View2.superview cache:YES];
[self.View2 removeFromSuperview];
[self performSelector:#selector(replaceViews2) withObject:nil afterDelay:0.6];
[UIView commitAnimations];
I have one view controller which contains two views (redView, blueView). The views are smaller than the main view.
I want to change from redView to blueView with animation. If use this none animation happens.
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
forView:redView cache:YES]; // !!! I WILL CHANGE THIS
[self.view addSubview:blueView];
[redView removeFromSuperview];
[UIView commitAnimations];
In case I change the code to this, then the animation is ok but the whole mainView animates, something that i do not want to happen. I want only the subViews to flip. I should note that the 2 subviews are in the same position. (frame) Any ideas?
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
forView:self.view cache:YES];
[self.view addSubview:blueView];
[redView removeFromSuperview];
[UIView commitAnimations];
Use Block animation instead of simple animation, from apple about simple animation "Use of the methods in this section is discouraged in iOS 4 and later"
Animation With Block's
[UIView transitionWithView:containerView
duration:1.25
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^
{
[redView removeFromSuperview];
[containerView addSubview:blueView];
}
completion:NULL];
containerView : is main view that will be animated.
Also add to your containerView redView,
that all :)
for more info look at
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html
Solution Found:
I use a tempView for which i do the animation. Onto the tempView I add view1 and view2.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:tempView cache:YES];
[tempView addSubview:view2];
[view1 removeFromSuperview];
[UIView commitAnimations];
Extra: For a better animation you can use view1.visible = YES , NO instead of addSubview, removeFromSuperView, but they will be allocated all the time
In your first example it looks like you are deleting the redView before it can animate, try deleting it after the animation.
Code:
[UIView setAnimationDidStopSelector:#selector(removeRedViewFromSuperview)];
I have a working view animation, that curls up a container view, while the containerview.subviews changes. (before the animation a UITableView will be shown, after it is a custom view, name keypadView)
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
forView:containerView
cache:YES];
[secondView removeFromSuperview];
[containerView addSubview:keypadView];
[UIView commitAnimations];
Now I want to rewrite this code for the iOS4 block-based api, as I want to use the completion block. I wrote this:
[UIView transitionWithView:containerView
duration:.75
options:UIViewAnimationTransitionCurlUp
animations:^{
NSLog(#"Hey Ho");
[secondView removeFromSuperview];
[containerView addSubview:keypadView];
}
completion:NULL];
The views switch — but not animated.
what is wrong with my code?
Edit
completion: ^(BOOL completed){
NSLog(#"completed %d", completed);
}
doesn't help, as NULL is an accepted value, according to the docs
do:
options:UIViewAnimationOptionTransitionCurlUp
instead of:
options:UIViewAnimationTransitionCurlUp
That is why your code works now :).
The sample in the UIView class reference may be wrong - or maybe there's a bug with adding and removing views in the animations block object, but the only way I've been able to get it to work is as follows:
[secondView removeFromSuperview];
[containerView addSubview:keypadView];
[UIView transitionWithView:containerView
duration:.75
options:UIViewAnimationOptionTransitionCurlUp
animations:^{}
completion:^(BOOL finished) {
NSLog(#"finished %d", finished);
}];
Did you leave [UIView beginAnimations:nil context:nil]; above your new block?
Is the completion block always NULL? Try putting an NSLog statement in there or something. I don't know if NULL blocks would mess it up.
I have a UIScrollView and I'm calling scrollRectToVisible:animated:YES on it.
I would like to set the speed at which it is animated. Can that be done?
I ended up finding a solution. In my case, the scrolling was animated programmatically after launch, to mimic a slot machine (with 3 horizontal UIScrollViews). Was doing this with the scrollRectToVisible:animated: method.
I got to set a custom speed using UIView's beginAnimation:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:(abs(rMid-pMid)*0.3)];
scrollMid.contentOffset = CGPointMake(rMid*320, 0);
[UIView commitAnimations];
AnimationDuration depends on the distance the scroller has to move between each "drawing".
A modern version with blocks:
[UIView animateWithDuration:1.0 animations:^{
[self.scrollView scrollRectToVisible:CGRectMake(...) animated:NO];
} completion:^(BOOL finished) {
...
}];