I need to present a viewController as a formSheet when the user taps a 'settings' button in the navigation bar in the iPad side of my universal app. The view is called "SettingsViewController," and it's a View Controller in my iPad Storyboard with an ID of "settings".
I'm not using segues because in my iPad version of the app, I have more than one button in the navigation bar on the left side, so I have to add the buttons progammatically. (can't connect a segue to a nonexistent UIBarButtonItem in the storyboard.)
The functionality I want is there, the presentation is not.
When I present my SettingsViewController, on the iPad, it's presenting as a full screen view.
I need it to be a form sheet.
I'm wrapping it in a NavigationController, which I need and works fine, just need it to present itself in the correct manner.
Here's the code that presents the view:
-(void)showSettings:(id)sender {
SettingsViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:#"settings"];
svc.delegate = self;
svc.modalPresentationStyle = UIModalPresentationFormSheet;
UINavigationController *navcont = [[UINavigationController alloc] initWithRootViewController:svc];
[self presentViewController:navcont animated:YES completion:NULL];
}
I've tried everything I can think of. Any help is deeply appreciated.
Looks like you set the modal presentation style on SettingsViewController but you should have set it on your UINavigationController.
navcont.modalPresentationStyle = UIModalPresentationFormSheet;
Related
I am updating our app to be compiled with xcode6/iOS8.
One issue I am running into is that when a modal view is presented. the underlying subview is removed. It is completely blacked out.. until the modal view is dismissed.. then it re-appears.
Has anyone run into this with iOS8? The same code has worked since iOS4.
Code:
PigDetailViewController *pigDetailViewController = [[PigDetailViewController alloc] initWithNibName:#"PigDetailViewController" bundle:nil];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
self.navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:pigDetailViewController animated:YES completion:nil];
In iOS 8 they've added a new presentation style that behaves like UIModalPresentationCurrentContext in the circumstance you've described, it's UIModalPresentationOverCurrentContext. The catch here is that unlike with UIModalPresentationCurrentContext, you want to set the view controller to be PRESENTED with this presentation style, like so:
PigDetailViewController *pigDetailViewController = [[PigDetailViewController alloc] initWithNibName:#"PigDetailViewController" bundle:nil];
pigDetailViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
self.navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:pigDetailViewController animated:YES completion:nil];
Note that to support iOS 7 and below you'll likely need to check the OS version and decide how to present the view controller based on that.
edit: I'd like to add one more note to this. In iOS7 with UIModalPresentationCurrentContext, when the presented VC was dismissed, the underlying VC had its viewDidAppear method called. In iOS8 with UIModalPresentationOverCurrentContext, I've found the underlying VC does not have its viewDidAppear method called when the VC presented over top of it is dismissed.
Adding a point to BrennanR's answer.. even viewWillAppear doesn't call when the VC presented over top of it is dismissed.
I think you are misunderstanding how a modal view controller works.
When you present a view controller modally it will control the entire screen. It has an opaque background (normally black) and then draws its view on top of that.
So, if you set the view.backgroundColor to yellow (for example) it will have a yellow background. If you set it to clear then it will show through to the black background.
What I think you want is for the other view to "show through" so it looks like the modal view is sitting on top of it.
The best way I have found of doing this is to use this method...
// in the view controller that is presenting the modal VC
modalVC = // the modal VC that you will be presenting
UIView *snapshotView = [self.view snapshotViewAfterScreenUpdates:NO];
[modalVC.view insertSubView:snapshotView atIndex:0];
// present the modal VC
This will take a "screenshot" of the current view hierarchy and then place that snapshot underneath everything in the modal VC.
That way your black screen will be replaced by a screenshot of the previous view controller.
I'm new to xcode ios 7.
I've struggling a lot with navigation controls building app for iPhone ios7.
I don't want to use storyboard. I prefer to do it programmatically.
What i am trying to do.
I know how to create NavigationBar & Navigation Toolbar via AppDelegate.m
But if it's possible i don't want to do it, because let's assume i want in FirstViewController to show just simple button "Go to Second View Controller" (No Navigation Bar or Toolbar here).
And now in SecondViewController i want to create Navigation Toolbar (bottom) with 4 different tabs linking to ViewControllers!
But the trick is, i want to maintain different Navigation Bar (top) for every ViewController (as you can see in this screenshot).
Here is my Xcode Project File
And here is screenshot form Fancy app showing what i am trying to achieve.
Thanks a lot in advance!
Just to give you an idea, When you tap the button on your first view controller, you can create a UINavigationController and set your second view controller as its root view controller. This way, your first view controller remains no nav bar view and the second view controller holds a Navigation controller. Try something like below:
-(IBAction)goToSecondVC:(id)sender // An action for the button in your first VC
{
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil]; //Init with second view controller
UINavigationController *secondNavVC = [[UINavigationController alloc] initWithRootViewController:secondVC]; // create a navigation controller and set the root as your second view controller
[self presentViewController:secondNavVC animated:YES completion:nil]; // and then present it with anim or no anim..
}
I am converting an iPhone App to an iPad App. I wish to present several of the view controllers as popovers that were previously pushed on the iPhone by changing the segue type in the storyboard from push to popover. The view controllers have a title, a done button, and a cancel button in the navigation bar. Now, when I run the iPad App the popover appears but without the navigation bar. How can I get the navigation bar to show. I have already tried expected setting it not hidden in viewWillAppear which did not work.
I have been able to change the segue to an IBAction with the following code and got it to work. It seems somehow the popover does not have a navigation controller so I created one. `
// Device is iPad
addNoteVC = [self.storyboard instantiateViewControllerWithIdentifier:#"addNoteVC"];
popoverNav = [[UINavigationController alloc] initWithRootViewController:addNoteVC];
[addNoteVC setManagedObjectContext:self.managedObjectContext];
[popoverNav.navigationBar setTintColor:[UIColor darkTextColor]];
NSDictionary *textAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor darkTextColor],NSForegroundColorAttributeName,nil];
[popoverNav.navigationBar setTitleTextAttributes:textAttributes];
[addNoteVC setSelectedClient:selectedClient];
[addNoteVC setAddNoteTableViewControllerDelegate:self];
popover = [[UIPopoverController alloc] initWithContentViewController: popoverNav];
[popover setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
popover.delegate = self;
[popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
`
While the above code works it creates significant differences from the iPhone App code. I would rather that the iPhone and iPad stayed the same as much as possible. If adding a another navigation controller for the popover is the only solution I would prefer to do this in a custom segue so the view controller code can stay the same. In addition that approach would have the economy of one custom segue instead of changes for every view controller presented as a popover. If that indeed is the best solution, details on the custom segue would be appreciated and accepted.
So in my universal app I have a section where a person can look at an existing list of notes from our system (retrieved through a simple web service) and then also create a new note if they want. So for the iphone it's pretty simple layout, a TableViewController for displaying the list with a "Add" button on the NavigationBar that presents the modalview for adding the new item. On the iPad though, the same layout has a lot of wasted space so I opted to go with the popOver method to show the list in a popOver and then let them add from there. My problem is that when the user clicks on the Add button within the PopOver view, the modal view comes up full screen instead of just coming up within the popover view. Here's the code I have so far:
-(void) AddButtonPressed:(id)sender {
NewNoteVC *newNote = [[[NewNoteVC alloc] initWithNibName:#"NewNoteVC" bundle:nil] autorelease];
newNote.defaultClientID = defaultClientID;
UINavigationController *navCon = [[[UINavigationController alloc] initWithRootViewController:newNote] autorelease];
if ([isPopOver isEqualToString:#"YES"]) {
[navCon setModalInPopover:YES];
[self.navigationController setModalInPopover:YES];
[self.navigationController presentModalViewController:navCon animated:YES];
}
else {
[self.navigationController presentModalViewController:navCon animated:YES];
}
}
The "isPopOver" string is just a placeholder sent from the previous screen that called this TableView (I know I can switch this to a boolean for better performance I just put this together real quick to try it out). I know I messed up somewhere, I just don't know what setting I need to get this working correctly.
You need to define the view controller's modalPresentationStyle to be "current context".
navCon.modalPresentationStyle = UIModalPresentationCurrentContext;
This will result in modal view controller filling the popover like the popover's root controller.
Try using the presentViewController:animated:completion: instead of presentModalViewController:animated: and set self.navigationController.definesPresentationContext = YES
Im trying to load a modal view from a view controller that is displayed in a popover. The modal view loads but the problem is that it transitions into the main view and not within the popover. Is it something Im missing? I thought simply initiating it from a vc within a popover would present the modal view within the same popover...
The code is nothing special as bellow:
- (IBAction)myButton{
ModalVC *controller = [[ModalVC alloc] initWithNibName:#"ModalVC" bundle:nil];
[self presentModalViewController:controller animated:YES];
[controller release]; }
If you add
controller.modalPresentationStyle = UIModalPresentationCurrentContext;
before the call to presentModalViewController:animated your ModalVC should be displayed within the popover.
Another way to display something modally in a popover is to use the property modalInPopover.
Unfortunately, it seems you cannot to this and it violates the HIG. From Apple's View Controller Programming Guide
Note: You should always dismiss the visible popover before displaying
another view controller modally. For specific guidelines on when and
how to use popovers in your application, see “Popover (iPad Only)” in
iOS Human Interface Guidelines.
It's because you presentModalViewController to self. Try to add a UIBarButtonItem in your ViewController (self) and do:
[controller presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
where sender is the UIBarButtonItem