iphone - not full screen modal - iphone

At some part of my code I am using this line
[[self navigationController] pushViewController:myController animated:YES];
This works perfectly and pushes a view, coming from bottom, over the current one, covering the last one completely.
I am wondering if there's a way to make it cover just part of screen. Let's say, just the half bottom of the screen...
Is it possible? I have tried to change the controller's view frame but the size kept coming full screen.
thanks.

Instead of using a new view controller modally, you could add a new subview to your existing view, using the same view controller.
You can do the "slide in" animation with something like:
[self.view addSubview: newView];
CGRect endFrame = newView.frame; // destination for "slide in" animation
CGRect startFrame = endFrame; // offscreen source
// new view starts off bottom of screen
startFrame.origin.y += self.view.frame.size.height;
self.newImageView.frame = startFrame;
// start the slide up animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.3];
newView.frame = endFrame; // slide in
[UIView commitAnimations];

You can do it in a limited fashion with a modal view controller. Check out the presentation options available under UIModalPresentationStyle in the apple docs.
You will need to be on iOS 3.2 or above to do a modal view controller.

Related

removeFromSuperview with animation and views management

I did some digging around about this, but nothing really seems to answer my particular question (not even this: Is it possbile to removeFromSuperview with Animation?).
Basically, my app starts with a welcome screen, where a user clicks on "sign in", then goes to the sign in view, then getting to a tab bar view, which is the actual app.
The way I did it, is that I wrote a custom class - TabBarController, which sets up all the tabs and their respective view controllers. Now, when the user clicks on "sign in" i am calling removeFromSuperview and present the tabbar.
I am trying to find a way to animate the transition from the sign in page to the tab bar. I tried some proposed solutions around here, but none seems to do the job. Here is my code in the signin.m view controller. I am looking to animate out the current view (ideally, not just by fading out, but more cool stuff like flips, etc.).
//when done signing in --> go to the tab bar view
-(IBAction)done:(id)sender {
TabBarController *tabController = [[TabBarController alloc] init];
[UIView beginAnimations:#"removeWithEffect" context:nil];
[UIView setAnimationDuration:4.0];
self.parentViewController.view.frame = CGRectMake(0,0,320,480);
self.parentViewController.view.alpha = 1.0f;
[UIView commitAnimations];
[self.parentViewController.view performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:2.5f];
[self presentModalViewController:tabController animated:YES];
}
Appreciate any help!
That can't work that way. presentModalViewController dislpays the view of a viewController over the own view. It won't replace the source viewController (self).
Since you remove self.parentViewController.view from the view hierarchy, it can't present your tabController modally because you have removed self.
Anyway, i would recommend you another way to achieve your view layout:
Create a tabBarViewController and add its view to a rootView (self.window in the app delegate or whatever you are using now). Then add your login-view to the same view. Due the view hierarchy, the login-view will be displayed above the tabBar.view. And the done button should be implemented this way: (i'm using block syntax for animation as it should be)
-(IBAction)done:(id)sender {
[UIView animateWithDuration:1.0
animations:^{
self.view.frame = CGRectMake(0, 480, 320, 480);
self.view.alpha = 0.0
}
completion:^(BOOL finished){
[self.view removeFromSuperView];
}
];
}
You can animate more things than just the alpha, size or position. Just take a look about animations in the documentation. I guess, you'll be interested in view.transform to commit flip animations. ;)
This is how you have to remove the view after animating it.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelay:2.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:myView];
[UIView setAnimationDidStopSelector:#selector(removeFromSuperview)];
[UIView commitAnimations];
Hope this helps.
Happy coding.

Animating UIView while pushing a UINavigationController

following situation.
i have an app that uses a UINavigationController for navigating.
For a push of a special Navigation Controller i want a custom Animation, a zoom out.
What i have is looking good so far, the only problem is, that the "old" Viewcontroller disappears before the animation starts, so the new viewcontroller zooms out of "nothing" instead of viewing the old viewcontroller in the background.
For better viewing i created a simple sample app: download
Does anybody know, how to animate the new viewcontroller (image3) that the old view controller(image1) stays in the background while animating (image 2)?
/* THIS CANNOT BE CHANGED */
AnimatedViewController *animatedViewController = [[AnimatedViewController alloc] initWithNibName:#"AnimatedViewController" bundle:nil];
/* THIS CAN BE CHANGED */
animatedViewController.view.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView beginAnimations:#"animationExpand" context:NULL];
[UIView setAnimationDuration:0.6f];
animatedViewController.view.transform=CGAffineTransformMakeScale(1, 1);
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
/* THIS CANNOT BE CHANGED */
[self.navigationController pushViewController:animatedViewController animated:NO];
Additional information: my app isn't that simple. i use three20 framework for my app but the pushing and creating of the view controllers is simply what three20 does. i only can hook into the part between (THIS CAN BE CHANGED in my code). i cannot change the code before and after this (except with a lot of researching).
I whipped this up very quickly. The idea is to call pushViewController after the scale animation is completed.
-(IBAction)animateButtonClicked:(id)sender {
animatedViewController = [[AnimatedViewController alloc] initWithNibName:#"AnimatedViewController" bundle:nil];
animatedViewController.view.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView animateWithDuration:0.6
animations:^{
[self.view addSubview:animatedViewController.view];
animatedViewController.view.transform=CGAffineTransformMakeScale(1, 1);
}
completion:^(BOOL finished){
[animatedViewController.view removeFromSuperview];
[self.navigationController pushViewController:animatedViewController animated:NO];
}];
}
Ok, one way to do this (a bit ugly) is to do the animation and upon the completion of the animation, do the pushViewController. When you do the animation, you need to animate up what the about-to-be-presented view controller's screen would look like. Since the animation ends with the new view, when the new view comes to the screen, nothing should change because its the same as the just animated view.

Adding a persistent UIView with a UITabBarController

I have an app using a UITabBarController, and I have another view that needs to slide up from behind the tab bar controls, but in front of the tab bar's content. If that's not clear, imagine an advertisement sliding up in a tabbed app that appears in front of everything except for the tab bar buttons.
So far I have code that looks something like this, but I'm willing to change it if there's a better way to do this...
tabBarController.viewControllers = [NSArray arrayWithObjects:locationNavController, emergencyNavController, finderNavController, newsNavController, nil];
aboutView = [[AboutView alloc] initWithFrame:CGRectMake(0, window.frame.size.height - tabBarController.tabBar.frame.size.height - 37 ,
320, window.frame.size.height - tabBarController.tabBar.frame.size.height)];
[window addSubview:tabBarController.view]; // adds the tab bar's view property to the window
[window addSubview:aboutView]; // this is the view that slides in
[window makeKeyAndVisible];
Currently aboutView is a subclass of UIView and sits at its starting position at the bottom, but it hides the tabBarController. How can I change this to let the tabs be on top, but still have the aboutView in front of the other content?
You need to add the aboutView as a subview of the view in the currently active view controller in the UITableBarController. You can access that view via the selectedViewController property.
You can add code to your aboutView implementation to animate the view when it appears.
I do something like this in a popup view that I want to appear under the tab bar controls. You can add some code to the didMoveToSuperview message on the aboutView implementation:
- (void)didMoveToSuperview
{
CGRect currentFrame = self.frame;
// animate the frame ... this just moves the view up a 10 pixels. You will want to
// slide the view all the way to the top
CGRect targetFrame = CGRectOffset(currentFrame, 0, -10);
// start the animation block and set the offset
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5]; // animation duration in seconds
[UIView setAnimationDelegate:self];
self.frame = targetFrame;
[UIView commitAnimations];
}
So when your aboutView is added to the selected view controller's view, it automatically animates up.

interfaceorientation remains same after removeFromSuperview and again addSubview

I am switching between views using view animations, its works but I am having an issue with interface orientation.
I have two views on window.
authenticationViewCont
mainViewCont
Both have a button, when button clicked on authenticationViewCont I remove it and show mainViewCont and vice versa.
Once I addSubview the authenticationViewCont.view and putting device in portrait mode then removed it by removeFromSuperview then I change device orientation to landscape in my hands then again addSubview the authenticationViewCont. It first displayed animating in portrait and changing orientation after animation.
-(void)mainToAuthentication {
CGRect originalFrame = authenticationViewCont.view.frame;
CGRect modifiedFrame = originalFrame;
modifiedFrame.origin.y = originalFrame.size.height;
// made view out from screen
authenticationViewCont.view.frame = modifiedFrame;
// add sub view on top of other views
[self.window addSubview:authenticationViewCont.view];
// transiting view from bottom to center of screen
[UIView animateWithDuration:0.5
animations:^{ authenticationViewCont.view.frame = originalFrame; }
completion:^(BOOL finished){ mainViewCont.view removeFromSuperview; }];
}
-(void)authenticationToMain {
CGRect originalFrame = mainViewCont.view.frame;
CGRect modifiedFrame = originalFrame;
modifiedFrame.origin.y = -originalFrame.size.height;
// made view out from screen
mainViewCont.view.frame = modifiedFrame;
// add sub view on top of other views
[self.window addSubview:mainViewCont.view];
// transiting view from top to center of screen
[UIView animateWithDuration:0.5
animations:^{ mainViewCont.view.frame = originalFrame; }
completion:^(BOOL finished){ authenticationViewCont.view removeFromSuperview; }];
}
How can I make it to display in current interface orientation instead of old interface orientation in which it was removeFromSuperview?
I think the problem here is that you are initialliy adding one viewController.view ontop of another then removing the old one.
The problem with window only expects one rootViewController. So the window will only pass rotation events onto the first controller. Meaning your second viewController will not get rotation events until the completionsBlock gets called.
The way I would get around this is to put this switching code inside of a rootViewController that is on the window. Then whenever you do your switching you can pass in the current rotation of the rootviewController and have your authenticationViewController set itself up based on the orientation you pass it

how show animation when going to second view without using navigate controller?

In my test application (im learning) i have 2 view controllers.
on the first view i have button "go to second view".
what i want to do :
when user click the "go to second view", the first view move left and go out of the screen
and the second view will appear from the right and replace the first view.
now, this animation is happen when pushing and poping with navigate controller.
my question :
how can i do the same animation, without nav controller ?
You can add a view off screen to the right, and then you can animate it to a new frame on-screen. Another common use for this method is to animate modal menu views from the bottom. You can also animate other properties of the view, such as the alpha value to make a view disappear/reappear.
// the size of the screen minus the Status Bar
#define SCREEN_FRAME [[UIScreen mainScreen] applicationFrame]
// add the full-screen view offscreen to the right
CGRect frame = CGRectMake(SCREEN_FRAME.size.width,
SCREEN_FRAME.origin.y,
SCREEN_FRAME.size.width,
SCREEN_FRAME.size.height);
UIView *view = [[[UIView alloc]initWithFrame:frame]autorelease];
[self.view addSubview view];
// this is the frame the view will end on after the animation
CGRect newFrame = CGRectMake(SCREEN_FRAME.origin.x,
SCREEN_FRAME.origin.y,
SCREEN_FRAME.size.width,
SCREEN_FRAME.size.height);
// animate the transition
[UIView beginAnimations:nil context: nil];
[UIView setAnimationDuration: .5];
view.frame = newFrame;
[UIView commitAnimations];