Until now I have been using the code from this answer to simulate pushing a view. But now the view pushing animation changed. Does anyone have code to simulate the new animation?
I have found a way to simulate it, which is pretty pretty close to the original.
You have to add MTAnimation (which is needed for the exponential ease out). This library will need QuartzCore, so you will have to add it to your "linked libraries" in "build phases" within project settings if it isn't already added.
And here is the code:
push controller animation
// Get the views
UIView * fromView = sourceViewController.view;
UIView * toView = destinationViewController.view;
UIView *darkenView = [[UIView alloc] initWithFrame:fromView.frame];
[darkenView setBackgroundColor:[UIColor colorWithRed:255 green:255 blue:255 alpha:0]];
[fromView addSubview:darkenView];
// Get the size of the view area.
CGRect viewSize = fromView.frame;
// Add the new view to the old view.
[fromView.superview addSubview:toView];
// Position the new view outside of the screen
toView.frame = CGRectMake( viewSize.size.width , viewSize.origin.y, viewSize.size.width, viewSize.size.height);
[UIView mt_animateViews:[NSArray arrayWithObjects:fromView, toView, nil]
duration:.55
timingFunction:MTTimingFunctionEaseOutExpo
options:UIViewAnimationOptionAllowAnimatedContent
animations:
^{
// Animate the replacing of the views
fromView.frame =CGRectMake( -(viewSize.size.width/3) , viewSize.origin.y, viewSize.size.width, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, viewSize.size.width, viewSize.size.height);
[darkenView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:.1]];
}
completion:
^{
// Remove the old view
[darkenView removeFromSuperview];
[fromView removeFromSuperview];
}];
pop controller animation (like with the back button)
// Get the views.
UIView * fromView = sourceViewController.view;
UIView * toView = destinationViewController.view;
// Get the size of the view area.
CGRect viewSize = fromView.frame;
// Add the new view to the old view.
[fromView.superview insertSubview:toView belowSubview:fromView];
// Position the new view outside of the screen
toView.frame = CGRectMake( -(viewSize.size.width/3) , viewSize.origin.y, viewSize.size.width, viewSize.size.height);
UIView *darkenView = [[UIView alloc] initWithFrame:toView.frame];
[darkenView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:.1]];
[toView addSubview:darkenView];
[UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionAllowAnimatedContent animations:
^{
// Animate the replacing of the views
fromView.frame =CGRectMake(viewSize.size.width , viewSize.origin.y, viewSize.size.width, viewSize.size.height);
toView.frame =CGRectMake(0, viewSize.origin.y, viewSize.size.width, viewSize.size.height);
darkenView.frame = toView.frame;
[darkenView setBackgroundColor:[UIColor colorWithRed:255 green:255 blue:255 alpha:0]];
}
completion:^(BOOL finished)
{
if (finished)
{
// Remove the old view
[fromView removeFromSuperview];
[darkenView removeFromSuperview];
}
}];
Related
I am doing an app in which i need to draw lines in one view and that automatically should appear in the other view. Any help would be appreciated..
I have tried this..
- (void)viewDidLoad
{
[super viewDidLoad];
slv = [[SmoothLineView alloc] initWithFrame:CGRectMake(DrawingView.bounds.origin.x, DrawingView.bounds.origin.y + 42, DrawingView.bounds.size.width, DrawingView.bounds.size.height - 42)];
slv.delegate = self;
[DrawingView addSubview:slv];
}
-(IBAction)btnAnotherView:(UIButton *)sender
{
[zoomingTypingView setUserInteractionEnabled:YES];
if(sender.tag == 123)
{
[self.view setBackgroundColor:[UIColor colorWithWhite:0.500 alpha:1.000]];
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationTransitionCurlUp
animations:^{
//animation code
zoomingTypingView.frame = CGRectMake(0, 549, 768, 451);
} completion:^(BOOL finished) {
}];
CGRect imageFrame = CGRectMake(50, 50, 220, 120);
ResizableView = [[SPUserResizableView alloc] initWithFrame:imageFrame];
CGRect gripFrame = CGRectMake(50,50, 220,120);
UIView *zoom = [[UIView alloc]initWithFrame:gripFrame];
UIScrollView *zoomscroll = [[UIScrollView alloc]initWithFrame:gripFrame];
[zoomscroll setZoomScale:32.0];
[zoomscroll setMaximumZoomScale:32.0];
[zoom addSubview:zoomscroll];
[ResizableView setContentView:zoom];
ResizableView.delegate = self;
[DrawingView addSubview:ResizableView];
sender.tag = 246;
}
else
{
[UIView animateWithDuration:0.5
delay:0.1
options:UIViewAnimationTransitionCurlUp
animations:^{
//animation code
zoomingTypingView.frame = CGRectMake(0, 999, 768, 451);
} completion:^(BOOL finished) {
[self.view setBackgroundColor:[UIColor whiteColor]];
}];
[ResizableView removeFromSuperview];
[DrawingView addSubview:slv1];
sender.tag = 123;
}
}
In the above Image WhiteColored View is the new View and if i draw in that whiteColoredView that should reflect in both the views.
You can get more idea by looking at the NOTE TAKER HD APP.
http://www.youtube.com/watch?v=FdGDnUKZcMM
If you have two views defined:
#property(nonatomic) UIView *view1;
#property(nonatomic) UIView *view2;
instead of do self.view, you can have function does the drawing for one view:
-(void)drawView:(UIView*)view{
//your drawing code here
}
And just call the same function twice with passing different views.
In my app I want to launch UIViewController from top to bottom.So from FirstViewController I am launching MyWebViewController(which I need to animate) as follows:
MyWebViewController *theWebViewController = [[MyWebViewController alloc] initWithFrame:self.view.bounds];
[self.view addSubview:theWebViewController.view];
and In loadView of MyWebViewController I am assigning frame to view as follows;
- (void)loadView
{
CGRect theFrame;
theFrame = CGRectMake(0.0, 20.0, mFrame.size.width, 0.0);
UIView *view = [[UIView alloc] init];
view.frame = theFrame;
self.view = view;
[view release];
}
and In viewDidLoad I am changing the frame as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
[UIView beginAnimations:#"animateView" context: nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.5];
self.view.frame = CGRectMake(0.0, 20.0, mFrame.size.width, mFrame.size.height-20.0);
[UIView commitAnimations];
}
But the animation is not happening.I even tried this code to animate from bottom to top and it is working fine but vice-versa not working.Please can anyone tell me where I am doing wrong and how I can achieve?
Thanks in advance!
I wouldn't think to set the height to 0. Instead:
- (void)loadView
{
CGRect theFrame;
theFrame = CGRectMake(0.0, -mframe.size.height + 20, mFrame.size.width, m.frame.size.height - 20);
UIView *view = [[UIView alloc] init];
view.frame = theFrame;
self.view = view;
[view release];
}
You want to set the frame above and out of the view when you add it. Then move it into place in the animation.
I am trying to dismiss a view controller from bottom to top instead of the standard right to left transition. Is this at all possible? Here is the code I have so far:
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect endFrame = self.view.frame;
endFrame.origin.y = screenRect.origin.y - screenRect.size.height;
UIView *aView = [[self.view retain] autorelease];
[self.view.window addSubview:aView];
aView.frame = CGRectMake(0, 0, 320, 460);
[UIView animateWithDuration:0.5
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
aView.frame = endFrame;
}
completion:^(BOOL finished) {
[self dismissModalViewControllerAnimated:NO];
[aView removeFromSuperview];
}
];
This does result in a transition; but the previous view controller does not appear until after the animation since I can't dismiss until after it completes... any ideas?
Aah, when you presentModalViewController, it automatically hides the view behind. What you need to do is not present and remove, but add the view controllers view as a subview of the main view. Then you just animate the view offscreen, and removeFromSuperview in the competition handler.
I have a series of uiviews, and i want to create an animation where a button press event will expand the uiview from the bottom and reveal more information about the view. Another button press will shrink the view back to original.
How do i proceed with this?
There are a series of uiviews laid out in a horizontal scroll view like a coverflow. I want to display additional information about each uiview on click of a button.
Do drop a comment if you need more information.
TIA,
Praveen S
This code will expand your view...do the reverse to shrink it
CGRect tempFrame=view.frame;
tempFrame.size.width=200;//change acco. how much you want to expand
tempFrame.size.height=200;
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.2];
view.frame=tempFrame;
[UIView commitAnimations];
For that use this code
In .h file
#import <UIKit/UIKit.h>
#interface ExpandedViewController : UIViewController
{
UIView * expandiView;
BOOL viewExpanded;
}
- (IBAction)expandOrShrinkView:(id)sender;
#end
and in your .m file
- (void)viewDidLoad
{
[super viewDidLoad];
aview = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
aview.backgroundColor = [UIColor redColor];
[self.view addSubview:aview];
viewExpanded = NO;
}
And in your button action add this code
- (IBAction)expandOrShrinkView:(id)sender {
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
if (!viewExpanded) {
viewExpanded = YES;
aview.frame = CGRectMake(10, 10, 100, 200);
}else{
viewExpanded = NO;
aview.frame = CGRectMake(10, 10, 100, 100);
}
} completion:nil];
}
When you click the button first time it will expand the view from bottom and when you click the button second time it will shrink the View from bottom change the frame size to your need..
And if you want shrink function in another button than use two action method like this
- (IBAction)expandView:(id)sender {
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
aview.frame = CGRectMake(10, 10, 100, 200);
} completion:nil];
}
- (IBAction)ShrinkView:(id)sender {
[UIView animateWithDuration:0.8f delay:0.0f options:UIViewAnimationOptionTransitionNone animations: ^{
aview.frame = CGRectMake(10, 10, 100, 100);
} completion:nil];
}
I am displaying two images in my iPhone app, one on top, one on the bottom. They cover the entire screen. The user, with a swipe gesture, can change either of the images, depending on where the swipe started.
I want the image to change with an animated transition. It currently works without animation, or with the entire screen transitioning. Is it possible to make the transition occur over part of the screen?
I load the images for the first time (in viewDidLoad) thus:
// top image
UIImage *topImage = [UIImage imageNamed:#"top1.png"];
CGRect topframe = CGRectMake(0.0f, 0.0f, 320.0f, 240.0f);
UIImageView *topView = [[UIImageView alloc] initWithFrame:topframe];
topView.image = topImage;
[self.view addSubview:topView];
[topView release];
// bottom image
UIImage *bottomImage = [UIImage imageNamed:#"bottom1.png"];
CGRect bottomframe = CGRectMake(0.0f, 240.0f, 320.0f, 240.0f);
UIImageView *bottomView = [[UIImageView alloc] initWithFrame:bottomframe];
bottomView.image = bottomImage;
[self.view addSubview:bottomView];
[bottomView release];
When I detect a swipe, and detect which of the two images are to be changed, I call a routine like this one:
- (void)changeTopImage:(NSString *)newImage {
UIImage *topImage = [UIImage imageNamed:newImage];
CGRect topframe = CGRectMake(0.0f, 0.0f, 320.0f, 240.0f);
UIImageView *topView = [[UIImageView alloc] initWithFrame:topframe];
topView.image = topImage;
[self.view addSubview:topView];
[topView release];
}
Essentilly, I'm continually loading images on top of each other. Is that the best way to do it, especially in terms of memory management?
Everything else I've tried, using techniques such as below, make the entire screen transition:
[UIView beginAnimations:nil context:nil];
...
[UIView commitAnimations];
Thanks for any leads on which way I should be going on this.
well, an easy way could be this (repeat for the bottomImage):
don't release topView when you load it the first time in your method,
but declare it in your .h file,
and use a tempView too:
#interface YourClass: UIViewController{
UIImageView *topView;
UIImageView *tempView;
}
this way you can call them to move them and remove them when you load a new image
then in .m:
EDIT: some correction (see coco's comments):
[a] [b] line 4 = [c] line 11:
- (void)changeTopImage:(NSString *)newImage {
UIImage *topImage = [UIImage imageNamed:newImage];
//CGRect topframe = CGRectMake(0.0f, 0.0f, (320.0f + 320), 240.0f);
CGRect topframe = CGRectMake((0.0f + 320), 0.0f, 320.0f, 240.0f);
tempView = [[UIImageView alloc] initWithFrame:topframe];
//topView.image = topImage;
tempView.image = topImage;
[self.view addSubview:tempView];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView beginAnimations:#"animation" context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
tempView.center = topView.center;
// do this to push old topView away, comment next line if wanna new image just cover it
//topView.center = CGPointMake(topView.x - 320, topView.y);
topView.center = CGPointMake(topView.center.x - 320, topView.center.y);
// call a method when animation has finished:
[UIView setAnimationDidStopSelector:#selector(endOfAnimation:finished:context:)];
[UIView commitAnimations];
}
- (void)endOfAnimation:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[topView removeFromSuperview];
topView = tempView;
[tempView release];
tempView = nil;
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
- (void)dealloc {
if (tempView != nil) {
[tempView release];
}
[topView release];
[super dealloc];
}