Why is modal presentation form sheet not being displayed as expected? - ios

I'm just trying a really simple example here as I start to delve into iOS development for ipad.
I'm creating a split view and immediately trying to present a modal form sheet.
Should be really basic.
With what I've tried I get what behaves like a page sheet instead.
In landscape I can see the split view beneath but I don't see the top of my modal view (the tool bar is hidden but is in view in portrait).
I would expect to just grey out the split view beneath a 540x620 modal dialog. I should see the split view beneath my modal in both portrait and landscape like all the nice form sheet dialogs in the Cheddar app for example.
I must be doing something wrong here but all the examples I've read and same within the Cheddar app are doing pretty much what I outline below.
In the app delegate:
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.detailViewController = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
self.window.rootViewController = self.splitViewController;
[self.window addSubview:self.splitViewController.view];
ModalViewController *modalView = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:modalView];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self.splitViewController presentViewController:navController animated:NO completion:nil];

The app delegate is way too soon. You have no interface yet, so you can't coherently do any presenting of any view controller.
So, first thing, move all your modalView code to the viewDidAppear: of your detailViewController.

Related

Master from split view controller is showed over the tab bar

I have a tab bar controller with three tabs that I set programmatically. The two first ones are just UIViewController but the third one is an UISplitViewController that I get from another storyboard. Everything works great but when I'm on portrait mode and show the master view, this one is showed on top of the tab bar. I would like keep showing the full tab bar.
This also generate problems when trying to show an UIAlertController from an item bar button in the master view (this button doesn't exist in the image) as the popover is showed behind the master view.
Does anyone know how can I workaround this?
The way I set them programmatically is this (in case it may help):
UIViewController *view1 = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"FirstView"];
UIViewController *view2 = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"SecondView"];
UIViewController *view3 = [[UIStoryboard storyboardWithName:#"StoryboardSplit" bundle:nil] instantiateViewControllerWithIdentifier:#"MySplitView"];
UISplitViewController *splitViewController = (UISplitViewController *)view3;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;
splitViewController.delegate = self;
NSMutableArray *tabViewControllers = [[NSMutableArray alloc] init];
[tabViewControllers addObject:view1];
[tabViewControllers addObject:view2];
[tabViewControllers addObject:splitViewController];
[self setViewControllers:tabViewControllers];
view1.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"view1"
image:[UIImage imageNamed:#"view1"]
tag:1];
view2.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"view2"
image:[UIImage imageNamed:#"view2"]
tag:2];
view3.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"view3"
image:[UIImage imageNamed:#"view3"]
tag:3];
Try importing QuartzCore, then setting TabBarController.tabBar.layer.zposition = 1. Of course replacing the necessaries like tabBar with the name of your tab bar and so on. This is works in Swift however through your own initiative you can work this into Obj-C

navigating to ViewControllers that aren't on the UITabBar

I started using UITabBarController and it is great.
The thing is I have a few views that aren't accessed from the UITabBar
(either presented modal programatically or we want to have a button on the top to jump to them)
The thing is that I want to retain the Tab bar visible in these views.
From my understanding mixing presentViewController and UITabBarController is problematic.
How can I do that? Can I have "hidden" tab bar elements I can reference programatically?
Just to clarify with an example:
Views A,B,C,D are in the tab bar - via the storyboard - everything is peachy.
I NEED to have views E and F clickable from the top navigation (please don't suggest a sliding TabBar or a multiple line UITabBar).
I could just jump to E and F but I want the UITabBar to still be visible so the user can jump from E to A for example.
Just use the good old UINavigationController for every tab and just use [self.navigationController pushViewController:A animated:YES];
That's how the setup looks in code:
SGTabBarViewController *rootVC = [[SGTabBarViewController alloc] init];
SGFirstTabViewController *firstVC = [[SGFirstTabViewController alloc] init];
UINavigationController *navController1 = [[UINavigationController alloc] initWithRootViewController:firstVC];
SGSecondTabViewController *secondVC = [[SGSecondTabViewController alloc] init];
UINavigationController *navController2 = [[UINavigationController alloc] initWithRootViewController:secondVC];
SGThirdTabViewController *thirdVC = [[SGThirdTabViewController alloc] init];
UINavigationController *navController3 = [[UINavigationController alloc] initWithRootViewController:thirdVC];
SGForuthTabViewController *fourhtVC = [[SGForuthTabViewController alloc] init];
UINavigationController *navController4 = [[UINavigationController alloc] initWithRootViewController:fourhtVC];
rootVC.viewControllers = #[navController1, navController2, navController3, navController4];
self.window.rootViewController = rootVC;
[self.window makeKeyAndVisible];
If you want your UITabBar visible on every VC you push just use hidesBottomBarWhenPushed = NO; on it.
However, there is no way to have UITabBar visible on views presented modally.

SplitViewController in only one of the existing 5 views?

I have 5 views in my app and I'm appDelegate by setting them in the following way:
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:navigationcontroller1, navigationcontroller7, navigationcontroller5, navigationcontroller4, navigationcontroller6, navigationcontroller2, nil];
self.window.rootViewController = tabBarController;
All of them come with a NavigationController and tabbarcontroller, But I needed to split the screen into two parts, in this case the screen would be divided would be navigationcontroller2, as you can see below:
VendaViewController *venda_viewcontroller = [[VendaViewController alloc] init];
UINavigationController *navigationcontroller2 = [[UINavigationController alloc] init];
[navigationcontroller2 pushViewController:venda_viewcontroller animated:YES];
Hence I tried the following way:
VendaViewController *venda_viewcontroller = [[VendaViewController alloc] init];
VendaDetailViewController *vendaDetail_viewcontroller = [[VendaDetailViewController alloc] init];
UISplitViewController *splitVC = [[UISplitViewController alloc] init];
[splitVC setViewControllers:[NSArray arrayWithObjects:venda_viewcontroller,vendaDetail_viewcontroller,nil]];
UINavigationController *navigationcontroller2 = [[UINavigationController alloc] init];
[navigationcontroller2 pushViewController:splitVC animated:YES];
But not work in this code, but in documentation of UISplitViewController is writing the following message:
"you must always install the view from a UISplitViewController object
as the root view of your application’s window. [...] Split view
controllers cannot be presented modally."
So...If I like to put a splitViewController in my view controller, I'll have to put splitViewController in all of my views controllers? Or have another solution to this?
You can use a UISplitViewController only as the root view controller of your app. In your case you can implement your custom container view controller with functionality similar to the split (two subview controller inside the main). Follow this link for details.

How to show the Navigation Bar in an iOS view?

I'm opening a View from the navigationController, using the NVSlideMenuController. However, I haven't been able to show a Navigation Bar (which I definitely need).
I'm not familiar with NavigationControllers and after following a few tutorials, it still isn't clear enough to me how it works.
This is in the AppDelegate application didFinishLaunching:
IntroViewController* introVC = [[IntroViewController alloc] initWithNibName:#"IntroViewController" bundle:nil];
UIViewController *menuViewController = [[MenuViewController alloc] initWithStyle:UITableViewStyleGrouped]; // Your menu view controller
UIViewController *contentViewController = (UIViewController*)introVC; // The initial content view controller
menuViewController.navigationController.navigationBarHidden = false;
NVSlideMenuController *slideMenuController = [[NVSlideMenuController alloc] initWithMenuViewController:menuViewController andContentViewController:contentViewController];
self.window.rootViewController = slideMenuController;
return YES;
I tried adding the code to put the navbarhidden to false and it doesn't seem to work. Is there something else I missed?
Any help is very appreciated!
MyViewController *myViewController = [[MyViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
self.window.rootViewController = navigationController;
This will set the UINavigationController as your root view controller. If you MUST use NVSlideMenuController (which I have 0 experience with but really don't think it is necessary), then you can do the first two lines I gave you, and set the navigationController as the root for the NCSlideMenuController.
I would recommend Apple's documentation for UINavigationController, it is an extremely useful thing to know:
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UINavigationController_Class/Reference/Reference.html

how to add uinavigationcontroller as a second view not as rootviewcontroller

i know how to add uinavigationcontroller as root view and also how to push view in uinavigationcontroller.
What i am confused in the first view which is a root view is a simple view with button when this button is tapped it will show second view.
I want this second view as uinavigationview.
any ideas how to do it, i tried to search for the solution but didn't get any nor any similar question is asked before.
basically i am trying to work without interface builder to learn things in depth.
assuming you are presenting the 2nd view controller modally
instead of
UIViewController *vc = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:vc animated:YES];
do:
UIViewController *vc = [[[UIViewController alloc] init] autorelease];
UINavigationController *nc = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
[self presentModalViewController:nc animated:YES];

Resources