Dismissing a modal view controller using a different animation than it was presented with - objective-c

I have an application that presents a view controller (for registering / logging in) with a container view, and two views as switched between eachother using horizontal flipping. The app itself can be used before registration. I'm looking to change the way this is handled with storyboarding.
So upon opening the app there's a login button. If the user taps login a view controller is presented using Cover Vertical animation. On the top left of this view controller is a button to Register. Tapping on that does modal segue with a Horizontal Flip animation. On the Register view controller there's Login and Cancel buttons. I want Login to return to the login screen, and Cancel to go back to the view controller that was displayed using the Cover Vertical animation. Getting it there is fine, but the animation used is the Horizontal Flip animation, and not a (un)Cover Vertical animation.
I'ved tried the following code:
self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
before dismissing the view controller, but it's still flipping instead of uncovering.
Thanks for the help!
~James

I see no reason that shouldn't work, but as an example here's the code I would use:
[self setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self dismissModalViewControllerAnimated:YES];
I suggest trying this, it works well for me.

for Swift you can call this:
viewController.modalTransitionStyle = .coverVertical
viewController.dismiss(animated: true, completion: nil)

Related

UIViewController auto rotate?

I setup my UIViewController in app delegate as self.window.rootViewController. For some reason I need open sign view as modal from my root view controller like:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.window.rootViewController presentModalViewController:signViewC animated:NO];
If I change device orientation in sign view, my root view controller doesn't change orientation and I get incorrect orientation after sign view dismissed. Is it possible to change root view orientation if I changed orientation in sign view?
In my root controller I added:
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
And autorotation works if I rotate root view without modal view.
First of all, you shouldn't be presenting a modal from your app delegate. Whatever check you are doing to determine if you should present that view controller should be done in your main view controller. From there, you should call the code to present the modal, like so:
[self presentModalViewController:signViewC animated:NO]
That way, your main view controller isn't dismissed, it's only pushed down the view stack and should still respond to rotation notifications.
Try that out and let me know how it turns out.
EDIT
Take out the ModalPresentationStyle. That's what's messing you up.

how to load UITabBarController?

I have a code that currently loads a NIB file like below :
Login *monLogin = [[[Login alloc] init] autorelease];
[self presentModalViewController:monLogin animated:YES];
but the app is TabBar App (xcode template) and is suppose to also load the bottom menu.
how can I load this NIB file with the UITabBarController included?
my answer to your other question might help. But now I'm a little confused about what you're attempting to do. Let me know and I can help you further.
The modal view will not include the TabBar because a TabBar owns the view controllers represented by each tab. Why do you want the TabBar included in the login view? If you really want a TabBar in your modal view, then you'll need to put your 'log in' view controller inside a TabBar view controller, and then present the TabBar view controller modally.
However, I'd recommend that you have the TabBar in the main part of your app, and present the 'log in' view modally without a TabBar included. Once the user is finished logging in, you can dismiss the 'log in' view, which returns the user to the main part of your app.
To dismiss the modal view controller, set up a delegate system (look through the utility app template to see how this works). If setting up your own delegate protocol is too difficult at the moment, then you can use a workaround in the mean time. In your 'log in' view controller code, after the user has logged in successfully, you can send a message to your parent view controller (the one that presented the modal view) to dismiss it's modal view (your 'log in' view).
[self.parentViewController dismissModalViewControllerAnimated:YES];
This is bad form though. Once you're up to it you should use a delegate callback to have the parent view controller dismiss the modal view.

close UIPopover on rotation with a fadeout animation

The Apple Pages and Numbers apps have popovers (for "tools" etc) that close with a lovely fade out effect when you rotate the device. I'm trying to recreate this, but my popovers always seem to close instantly, so the animation of the rotation doesn't look quite as smooth. I'm currently using:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
[toolsPopoverController dismissPopoverAnimated:YES];
}
Does anyone know the best way to achieve the same effect seen in Pages/Numbers?
Thanks!
Based on the documentation for the UIPopoverController (emphasis added):
If the user rotates the device while a popover is visible, the popover controller hides the popover and then shows it again at the end of the rotation. The popover controller attempts to position the popover appropriately for you but you may have to present it again or hide it altogether in some cases. For example, when displayed from a bar button item, the popover controller automatically adjusts the position (and potentially the size) of the popover to account for changes to the position of the bar button item. However, if you remove the bar button item during the rotation, or if you presented the popover from a target rectangle in a view, the popover controller does not attempt to reposition the popover. In those cases, you must manually hide the popover or present it again from an appropriate new position. You can do this in the didRotateFromInterfaceOrientation: method of the view controller that you used to present the popover.
It would appear that by calling [toolsPopoverController dismissPopoverAnimated:YES] in the willAnimateRotationToInterfaceOrientation: method, you are dismissing with an animation while the popover is hidden during the rotation transition.
If you call the dismissPopoverAnimated:YES method in the didRotateFromInterfaceOrientation: method instead, the default behavior with the popover in the new position should present before the dismiss animation is invoked.
If the default animation is still not what you are looking for at this point, I would create a custom animation block and manage the fadeout or re-sizing explicitly to meet your desired needs.
This worked for me by calling dismissPopoverAnimated: from willRotateToInterfaceOrientation:duration:.

Flip Animation in a navigation controller's view

i am testing all day on this but i can not get it to work.
I have my main App Delegate class with my MainWindow.xib.
In this main class i create my navigation controller and MainWindow points to my MainViewController.xib. In this MainViewController i have a simple tableview, where i push some views on the navigation stack.
Till here it's working great.
But i want the user to switch between two styles of presenting him data.
One is the tableview, and the other option is something like a map. Doesn't matter. Just 2 different Views. So i thought of using a button on my nav bar to flip between these two views.
Don't get this subview flip to work.
I tried it with that source but didn't get it to work.
Some hints would be great!
Suppose you have all the navBar, buttons ready. You can use modal view for the solution:
-(void)changeView{
//create some view
[youNewView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:youNewView animated:YES];
}
You can use the above method to flip to a new view.
-(void) dismissView{
[self dismissModalViewControllerAnimated:YES];
}
and use the second method in the new view to flip back.
I like this method a lot because you don't need to add any controller manually at all.

UINavigationController without NavigationBar

I have a "landing page/view" that I dont want the navigation bar to show, so I turn it off during the viewDidAppear
navigationBarHidden = YES;
When i push a view on the stack and then move it off. the main landing page shows the nav bar then hides it which cause a flicker that I dont want.
is there a way to have the landing page be a UIView or something? When a menu item is touched the app would push a new view on top of the default landing page. It sound like it would be hard to do without having the landing page be a UINavigationController. Any thoguhts?
Try hiding the navigation bar in viewWillAppear, rather than viewDidAppear.
If you don't need to go back to the landing page, use a view controller for the landing page and present it modally from the navigation controller when the application starts.
So you do want to go back to the landing page.
It's hard to accomplish that with UINavigationController. Suppose your are going back to the landing view. While the transition, the old view should have a navigation bar, and the new view (landing page) should not have a navigation bar. UINavigationController does not allow you manually modifying the transition animation. In other words, you cannot animate hiding/unhiding the navigation bar along with push/pop animation (using viewWillAppear doesn't solve the problem).
So what would I do, if I really, really need this?
I would have a rootViewController (of UIViewController), whose view is the only subview of your application window. When your application starts, rootViewController add the landing view as a subview of its view. When the user selects an item there, you create an UINavigationController with the corresponding view controller as its root view controller.
And, using CATransition animation with type of kCATransitionPush and subtype of kCATransitionFromRight, you add the view of the navigation controller as a subview of rootViewController's view.
Then you need a 'back' button for the first view of the navigation controller. In all view controllers that are the first level view controllers of the navigation controller, create a bar button item with a text 'Back', and add it to their navigationItem.leftBarButton property. Set a target-action (probably to the rootViewController) pair for the button.
When the action message fires, use CATransition animation (now with kCATransitionFromLeft subtype), to remove the current navigation controller's view from rootViewController's view.
The transition may not look as perfect as the native UINavigationController, but I believe this is the best you could get.
Actually the way to do this is to implement UINavigationController's delegate method navigationController:willShowViewController:animated. This method is where you should handle hiding and showing your navigation bar so the animation will occur during the push/pop animation.
I came across a method that is simple and works well for me, and is not given here yet. I assume you have a view controller for the main landing page and it is set as root view controller of the navigation controller. Then you should hide/show the navigation bar in the viewWillAppear and viewWillDisappear methods of the main landing page controller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
Source:
http://www.iosdevnotes.com/2011/03/uinavigationcontroller-tutorial/