swapping views with cool page turn animation - objective-c

Below is code that I'm using to swap views
MySecondViewController *tempVC = [[MySecondViewController alloc] initWithNibName:#"MySecondView"];
[self presentModalViewController:tempVC animated:YES];
[tempVC passDataWithString:#"a string" andColor:yellowcolor];
How can I get the cool page turning animation (as with iBook or ROAD RAGE SIGN)
I don't want the user to actually tap and drag his finger on the screen. I want him to push a button and the animation occurs by itself.

Have you looked at UIViewAnimationTransition values? Use them in a UIView animation block. eg:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition: UIViewAnimationTransitionCurlUp
forView:self.view cache:YES];
[UIView commitAnimations];

Related

How to replace button with an animation in Xcode

I have a UIButton in my code that moves steadily across the screen. Currently, when the user presses the button, the alpha changes to 0 and it just disappears. What I'd like to do is run a separate animation after the button is pressed/it has disappeared. Seems easy enough but the catch is I need to run the animation at the exact point of the button when it is pressed. And I'm drawing a blank on how to make this happen. Any help will be much appreciated! I'll post some relevant code below.
-(void)movingbuttons{
movingButton2.center = CGPointMake(x, y);
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(moveObject)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
-(void)moveObject{
movingButton2.center = CGPointMake(movingButton2.center.x , movingButton2.center.y +1);
}
-(IBAction)button2:(id)sender {
[UIView beginAnimations:nil context:NULL];
[movingButton2 setAlpha:0];
[UIView commitAnimations];
}
Replace your button2 action with below code and implement the someOtherMethodWithAnimation method with the animation you want :)
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
movingButton2.alpha = 0;
[UIView commitAnimations];
[self performSelector:#selector(someOtherMethodWithAnimation) withObject:nil afterDelay:1.0];
Replace your animation with:
[UIView animateWithDuration:0.25
animations:^{
self.movingbutton2.alpha = 0.0;
// modify other animatable view properties here, ex:
self.someOtherView.alpha = 1.0;
}
completion:nil];
Just a nit picking point, but is the button in your view controller's .xib file correctly hooked up to your IBOutlets and IBActions?
UPDATE:
You are not limited to modifying that one button in your method. You add what ever code you want in the animation block (see the udated axample above).
UIView animatable properties, there is an animation section there.
Another approach could be (I am just using alpha as an example):
[UIView animateWithDuration:1.0
animations:^{
self.movingButton2.alpha = 0.0;
}
completion:^{
[UIView animatateWithDuration:0.25
animations:^{
self.someOtherView.alpha = 1.0;
}
completion:nil];
}];
This will more likely guarantee the animations will hapen one after another.

Fading UIView allows subviews to be seen

I have a UIScrollView which contains various subviews (UIImageViews, UILabels and standard UIViews). Some of the UIImageViews are partially covered by other UIViews.
However, when I fade out the UIScrollView, the partially covered parts of the UIImageViews are being exposed for the brief moment of the animation.
I want to be able to fade the scrollview and all it's contents at the same time in the same animation - i.e. not revealing any of the partially covered images.
If it's not possible, I can always add a UIView on top of all the other controls and fade it from alpha 0 upto 1 to hide everything, but I'm sure there's a way to perform a complete fade on a view and all it's subviews.
I tried this:
[UIView beginAnimations:nil context:NULL];
[scrollViewResults setAlpha:0.0f];
[UIView commitAnimations];
And I've tried this:
- (IBAction)questionGroupChanged:(UIButton*)sender {
[UIView beginAnimations:nil context:NULL];
[self fadeViewHierarchy:scrollViewResults toAlpha:0.0f];
[UIView commitAnimations];
}
- (void)fadeViewHierarchy:(UIView*)parentView toAlpha:(float)alpha {
[parentView setAlpha:alpha];
for (UIView *subView in parentView.subviews) {
[self fadeViewHierarchy:subView toAlpha:alpha];
}
}
But I've still not cracked it. Any ideas?
This happens because of the way the compositor works. You need to enable rasterization on the view's layer when fading it in/out:
view.layer.shouldRasterize = YES;
You should probably only enable this for the duration of the animation because it will take up some extra memory and graphics processing time.
Mike's answer is the correct one and he deserves all credit for this. Just to illustrate, it might look like:
- (void)fadeView:(UIView*)view toAlpha:(CGFloat)alpha
{
view.layer.shouldRasterize = YES;
[UIView animateWithDuration:0.75
animations:^{
view.alpha = alpha;
}
completion:^(BOOL finished){
view.layer.shouldRasterize = NO;
}];
}
Thus, using your scrollViewResults, it would be invoked as:
[self fadeView:scrollViewResults toAlpha:0.0f];
Did you try with UIView class methods +animateWithDuration:* (available on iOS 4 and +)
Like :
- (void)fadeAllViews
{
[UIView animateWithDuration:2
animations:^{
for (UIView *view in allViewsToFade)
view.alpha = 0.0;
}
completion:^(BOOL finished){}
];
}

I want to slide a transparent menu in from the left

I would like to implement a menu as shown above. I'm a total iOS newbie. I've been searching for that kind of control since couple of days.
Can someone guide me step by step, from scratch?
You can implement the above in following steps :-
1>Left Menu view is a UIView added as a subview with various cutom UIButtons over it added as subview.
2>Initially you have to set the frame so that only a particular part of the view is shown(Panel Part).
3> On the click of indicator button , expand the frame to its full to show the buttons.
4>On next click i.e(odd clicks) collase the frame.
Above animation can be achieved using simple UIView Animation.
Sample code(Original frame width=300,Height 300) :-
yourMenuView.frame=CGRectMake(0,10,100,300);
[yourViewController addSubview:yourMenuView];
-(IBAction)expandMenu:(id)sender
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
CGRect frame=yourMenuView.frame;
frame.size.width+=200;
yourMenuView.frame=frame;
[myview removeFromSuperview];
[UIView commitAnimations];
}
-(IBAction)collapseMenu:(id)sender
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
CGRect frame=yourMenuView.frame;
frame.size.width-=200;
yourMenuView.frame=frame;
[myview removeFromSuperview];
[UIView commitAnimations];
}

Stop user interaction on view

My code does an animation that flips from right to left. The problem is while its switching, only a .75 second animation, the user is still able to interact with the program. I dont want them to be able to, is there a way to stop all user interaction for a short time, or just a way to stop it completely, then i can just use a timer to put it back on. here is my code for the animation:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:[self view]
cache:YES];
[UIView commitAnimations];
Thanks, Jacob
Try:
[self.view setUserInteractionEnabled:NO];

How to let two animations for UIView executed one by one

I have a small UIView and want to let it move to center of screen first, and then, zoom to full screen.
But when I begin start an animation like
[UIView beginAnimations:#"animation1" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(showDetailToFullscreen)];
self.currentDetailVC.frame = centerFrame;
[UIView commitAnimations];
And in the same controller, I have a method:showDetailToFullscreen
- (void)showDetailToFullscreen {
CGRect screenFrame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
[UIView beginAnimations:#"animation2" context:nil];
[UIView setAnimationDuration:0.5];
self.currentDetailVC.view.frame = screenFrame;
[UIView commitAnimations];
}
but when start, it still executed together.
I think the problem they are still in the same transaction. But how can I let these two animation executed one by one? Appreciate for any answer!
Try this instead of the setAnimationDidStopSelector:
[self performSelector:#selector(showDetailToFullscreen) withObject:nil afterDelay:0.5];
It's now considered much better to annimate views using the 'blocks' methods that can be found in the "Animating Views with Blocks" section in the UIView Class Reference.
In most of these methods you can specify a "completion" block of code that can be used to start off a second animation when the first animation completes. You could also call showDetailToFullscreen within this completion block.
I'd reccommend trying this method instead.
Are you targetting iOS 4 or later? If so, I recommend using the block-based animation methods instead. What you want to do is very easy:
Example from UIView docs:
[UIView animateWithDuration:0.2
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];