I have a UIViewController view as a subview/modal on top of another UIViewController view, such as that the subview/modal should be transparent and whatever components is added to the subview should be visible. The problem is that I have is the subview shows black background instead to have clearColor. I'm trying to make UIView as a clearColor not black background. Does anybody know what is wrong with it? Any suggestion appreciated.
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];
SecondViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.opaque = YES;
self.view.backgroundColor = [UIColor clearColor];
}
RESOLVED: I fixed the issues. It is working so well for both of iPhone and iPad. Modal View Controller with no black background just clearColor/transparent. The only thing that I need to change is I replaced UIModalPresentationFullScreen to UIModalPresentationCurrentContext. How simple is that!
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: If you are using a modalPresentationStyle property of navigationController:
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: The bad news is that the above solution doesn't work on iOS 7. The good news is that I fixed the issue for iOS7! I asked somebody for help and here is what he said:
When presenting a view controller modally, iOS removes the view controllers underneath it from the view hierarchy for the duration it is presented. While the view of your modally presented view controller is transparent, there is nothing underneath it except the app window, which is black. iOS 7 introduced a new modal presentation style, UIModalPresentationCustom, that causes iOS not to remove the views underneath the presented view controller. However, in order to use this modal presentation style, you must provide your own transition delegate to handle the presentation and dismiss animations. This is outlined in the 'Custom Transitions Using View Controllers' talk from WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 which also covers how to implement your own transition delegate.
You may see my solution for the above issue in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions
iOS8+
In iOS8+ you can now use the new modalPresentationStyle UIModalPresentationOverCurrentContext to present a view controller with a transparent background:
MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:modalViewController animated:YES completion:nil];
RESOLVED: I fixed the issues. It is working so well for both of iPhone and iPad. Modal View Controller with no black background just clearColor/transparent. The only thing that I need to change is I replaced UIModalPresentationFullScreen to UIModalPresentationCurrentContext. How simple is that!
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: If you are using a modalPresentationStyle property of navigationController:
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: The bad news is that the above solution doesn't work on iOS 7. The good news is that I fixed the issue for iOS7! I asked somebody for help and here is what he said:
When presenting a view controller modally, iOS removes the view controllers underneath it from the view hierarchy for the duration it is presented. While the view of your modally presented view controller is transparent, there is nothing underneath it except the app window, which is black. iOS 7 introduced a new modal presentation style, UIModalPresentationCustom, that causes iOS not to remove the views underneath the presented view controller. However, in order to use this modal presentation style, you must provide your own transition delegate to handle the presentation and dismiss animations. This is outlined in the 'Custom Transitions Using View Controllers' talk from WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 which also covers how to implement your own transition delegate.
You may see my solution for the above issue in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions
So for purely visual thinkers and storyboard fans, you can do:
1. Presenting View Controller
2. Presented View Controller
Swift 3 & iOS10 solution :
//create view controller
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
vc.modalPresentationStyle = .overCurrentContext
//add clear color background
vc.view.backgroundColor = UIColor.clear
//present modal
self.present(vc, animated: true, completion: nil)
This is from xCode 7 beta 4 using a control drag segue. Simply set the background of your destination to clear, and set the segue properties in IB as this (nb. Presentation can also be "Over Full Screen"):
I found the easiest way to get it to work on iOS7 and iOS8 is to add set the presentationStyle to UIModalPresentationOverCurrentContext on the modallyPresentedVC (ViewController which you want to present modally) because of iOS8:
[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
and UIModalPresentationCurrentContext on presentingVC (the controller which presents the modallyPresented) because of iOS7:
[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];
Because things are handled differently on iOS7 and iOS8. Of course you don't have to set the navigationController properties if you are not using one. Hope that helps.
Swift2 version :
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen // orOverCurrentContext to place under navigation
self.presentViewController(vc, animated: true, completion: nil)
Another way (no need to create custom transition and works on iOS 7)
Using Storyboard:
Create the Child View Controller with freedom size, set view width to 500x500 (for example) and add the next method:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
self.view.superview.backgroundColor = [UIColor clearColor];
}
Then create a Modal segue with Form Sheet and test it.
iOS 7 solution with custom segue:
CustomSegue.h
#import <UIKit/UIKit.h>
#interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
#end
CustomSegue.m
#import "CustomSegue.h"
#implementation CustomSegue
-(void)perform {
UIViewController* destViewController = (UIViewController*)[self destinationViewController];
destViewController.view.backgroundColor = [UIColor clearColor];
[destViewController setTransitioningDelegate:self];
destViewController.modalPresentationStyle = UIModalPresentationCustom;
[[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}
//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
return 0.25f;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIView *inView = [transitionContext containerView];
UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[inView addSubview:toVC.view];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
[UIView animateWithDuration:0.25f
animations:^{
[toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
return self;
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
//I will fix it later.
// AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
// controller.isPresenting = NO;
// return controller;
return nil;
}
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
return nil;
}
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
return nil;
}
#end
Solution based on hightech code.
For Me this Works:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MMPushNotificationViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER)
{
self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
}
#endif
[self presentViewController:vc animated:NO completion:nil];
MMPushNotificationViewController is the Transparent View controller and also I have made the MMPushNotificationViewController's view color as clearcolor. Now All that I have Done and made my Transparentviewcontroller.
For iOS7
There is now a way to achieve this using the iOS7 custom transitions, this way :
MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];
To create your custom transition, you need 2 things :
A TransitionDelegate object (implementing
<UIViewControllerTransitionDelegate>)
An "AnimatedTransitioning" object
(implementing <UIViewControllerAnimatedTransitioning>)
You can find more informations on custom transitions in this tutorial.
Works Great on iOS7 and iOS8
UIViewController* vc=[[UIViewController alloc]initWithNibName:#"VC" bundle:nil];
vc.view.alpha=0.7;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
You also can 're-add' the window to the view.
OneViewController *vc = [[OneViewController alloc] init];
if ([self respondsToSelector:#selector(presentViewController:animated:completion:)]) {
[self presentViewController:vc animated:YES completion:nil];
} else {
[self presentModalViewController:vc animated:YES];
}
[[[UIApplication sharedApplication] keyWindow] insertSubview:self.view atIndex:0];
And in this way, presenting can be animated.
For iOS 7 and only by using Interface Builder it can be accomplished by setting the Presentation to "Over Current Context" on all the view controllers involved in the modal presentation. Even for navigation controllers.
For instance, set it on all these view controllers:
NavController -> RootViewController -> ModalViewController
I haven't played around with Storyboard/Interface builder much, but what pops out at me is that you're telling the view to be clear colored (ie. 100% alpha/see-through) and also telling it to be opaque (0% alpha--completely solid). These two things don't seem to mesh. I'd comment out the self.view.opaque = YES; line and see if it works then ;)
Ah, something else I just thought of--its entirely possible that your view controller DOES have the alpha background, but of course the alpha will be showing through to the color of the base window or root view controller of the program, which is by default black. The very base layer of your entire app can't have a transparent background--transparent to what? What's behind it? There has to be something to see THROUGH the transparency. Does that make sense?
Just use "self.modalPresentationStyle = UIModalPresentationCurrentContext;", in presenting view
Will work fine :)
Related
I have a pageview which contains 4 pages. The pageView is using a navigation bar from previous UIViewController. I want set my UIPageView button in navigation bar to go to a new UIView. there are few problems. When i use performSegueWithIdentifier("CrankSetViewController", sender: sender) it give me a black screen. How to change to new UIView programatically without getting black screen?
In Swift -
pageViewController.setViewControllers(startingViewControllers,
direction: UIPageViewControllerNavigationDirection.Forward,
animated: true,
completion: nil)
you can set this in #IBAction
You can programmatically set the currently displayed view controller with a transition animation using setViewControllers:direction:animated:completion: on your page view controller.
Here is an example that presents view controllers with random background colors. You can adjust this to use your specific view controllers.
- (void)viewDidLoad
{
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pvc.view.frame = CGRectInset(self.view.bounds, 200, 200);
[self.view addSubview:self.pvc.view];
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
-(UIViewController*)randomVC
{
UIViewController *vc = [[UIViewController alloc] init];
UIColor *color = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
vc.view.backgroundColor = color;
return vc;
}
- (IBAction)previousButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
}
- (IBAction)nextButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
Hope it will help you...
This question already has answers here:
Display clearColor UIViewController over UIViewController
(16 answers)
Closed 9 years ago.
Prior to iOS 7, according to this popular Stackoverflow question, the way to show a ViewController with a clear background was to do the following in the main ViewController:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
However, as I have recently discovered with iOS 7 (and as commented by others to the main answer), the above solution no longer works, and instead just shows a black model controller. I know that transparency is largely used in iOS 7, so that transparent view controller is very likely possible. I haven't discovered a workaround to this issue yet, and was wondering if anyone knows how to resolve this problem. Thanks!
I just followed the original solution and applied some default and custom settings in Interface Builder, and seems to me it is working.
You can check it here: https://github.com/codedad/SO_IOS_viewcl_on_viewcl
Important section (quite similar to the question's code):
- (IBAction)click:(id)sender {
NSLog(#"click");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"TopOverVc"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
}
Also pls find the IB snaphot:
And the simulator result (after pressing button):
Hope I did not misunderstand sthing in your question ;) Happy coding!
For iOS 7,subclass SecondViewController and try setting the view background color in viewDidLoad of SecondViewController
self.view.backgroundColor = [UIColor clearColor];
Why not u r using this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
vc.view.backgroundColor = [UIColor clearColor];
Try to change BG Color of View after view is loaded.
in ur sol u r first changing View and the presenting. the View Life cycle not going on this manner
I would like to modally add a view controller with a transparent background, so the parent view controller beneath can be seen. (This is in an app for iPhone, not for iPad.)
I have tried this:
TextFieldViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"TextFieldVC"];
vc.modalPresentationStyle = UIModalPresentationCurrentContext;
vc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self.navigationController presentViewController:vc animated:YES completion:^{}];
Without luck and given the view controller a clear color background. My view controller is in a storyboard if that changes anything.
#Josh Kahane
set the view controller that will present the transparent view controller with this code at the -ViewDidLoad
and be sure to set the alpha channel of the UIViewController View to be lower then 1.
Code:
self.modalPresentationStyle = UIModalPresentationCurrentContext;
I have been searching for the solution. Now thanks to iOS 8. They has introduced couple of new modalPresentationStyle. one among them is UIModalPresentationOverCurrentContext. Used the same to solve the this issue.
viewcontroller.modalPresentationStyle = UIModalPresentationOverCurrentContext;
Hope this helps.
For completeness and having it up-to-date, I am also adding the solution for Swift:
either
viewController.modalPresentationStyle = .CurrentContext
being - A presentation style where the content is displayed over only the presenting view controller’s content.
or
viewController.modalPresentationStyle = .OverCurrentContext
being - A presentation style where the content is displayed over only the parent view controller’s content. The views beneath the presented content are not removed from the view hierarchy when the presentation finishes. So if the presented view controller does not fill the screen with opaque content, the underlying content shows through.
Depending on the requirements and circumstances for the presentation.
It's possible although there are a bunch of steps which can be easily forgotten. After struggling with myself to get this working for 4 hours I came up with the following solution.
1 - Create a View Controller like any other.
Header file
#import "DDBaseViewController.h"
#interface DDHomeSearchLoadingViewController : UIViewController
#end
Implementation file
#import "DDHomeSearchLoadingViewController.h"
#interface DDHomeSearchLoadingViewController ()
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityMonitor;
#property (weak, nonatomic) IBOutlet UIView *modalView;
#end
#implementation DDHomeSearchLoadingViewController
#pragma mark - UIViewController lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
}
-(void) setupUI
{
[self makeRoundedCorner:self.modalView AndCornerRadius:6.0f];
[self.activityMonitor startAnimating];
}
-(void) makeRoundedCorner:(UIView*) view AndCornerRadius:(float) cornerRadius
{
[view.layer setCornerRadius:cornerRadius];
[view.layer setMasksToBounds:YES];
}
#end
2 - Set your container view background color as ClearColor
3 - Add a UIView which will be presented like an overlay
4 - Add a UIView which will be presented like a Dialog Box over the overlay UIView
Make sure it's outside the overlay view when you add/move it. For some reason when you move it using the mouse it adds to overlay UIView automatically. ( Freaking annoying to be honest )
5 - Set the Storyboard ID for the View you've created
6 - Finally add this piece of code wherever you wan't call it ( Assuming it's a UiViewController too )
DDHomeSearchLoadingViewController* ddHomeSearchLoadingViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"DDHomeSearchLoadingViewController"];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:ddHomeSearchLoadingViewController animated:YES completion:nil];
I hope it helps you guys out
Cheers
Answer for Swift 5.
TransparentViewController
self.view.backgroundColor = .clear
PresentingViewController
let viewController = TransparentViewController()
viewController.modalPresentationStyle = .overFullScreen
navigationController.present(viewController, animated: false)
Swift 3 -
Try vc.modalPresentationStyle = .overFullScreen
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("ExampleViewController") as! ExampleViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = .overFullScreen
self.presentViewController(vc, animated: true, completion: nil)
you can make changes in storyboard just by doing below options and also reducing parental view opacity. Using Storyboard: No need to write any code to achieve this
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
ChooseController *sec = [story instantiateViewControllerWithIdentifier:#"Controller"];
sec.modalPresentationStyle = UIModalPresentationOverCurrentContext;
sec.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:sec animated:YES completion:^{}];
Note: Present controller superview alpha value must be below 1 like 0.5 alpha like that.
When you modally present a view controller the , it goes on the stack which in turn hides the view controller below it. So all you can do is to present a transparent view with animation similar to modally presenting a view controller.
I'm using storyboards and I need to use subview to import a xib. The xib is simply to display an image. It has a UIImageView and a UIBarButtonItem. How do I set the image once I've imported it as a subview?
I've tried setting methods in the h+m files for the subview xib but maybe I'm doing it wrong. Here's my code
-(void)showPreviewImageScreen:(UIImage *)image
{
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController* vc = [sb instantiateViewControllerWithIdentifier:#"libraryImagePreview"];
[vc setPreviewImage:image];
[self.navigationController.view addSubview:vc.view];
}
The error i get says "No visible #interface for UIViewController declares the selector 'setPreviewImage'"
There isn't a method called setPreviewImage (as far as I know). You set the image with setImage: but that has to be called on your UIImageView that's in your xib, not on your view controller vc.
#rdelmar Thanks for pointing me in the right direction.. This is the solution I came up with..
I tagged the UIimageView with 1, then looped through the subviews to find this tag and target it this way.
-(void)showPreviewImageScreen:(UIImage *)image
{
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"libraryImagePreview"];
for (UIView *subview in vc.view.subviews)
{
if(subview.tag==1)
{
UIImageView *IV = subview;
[IV setImage:image];
}
}
[self.navigationController.view addSubview:vc.view];
}
here's my code:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
[self.navigationController presentModalViewController:vc animated:YES];
//[self setView:[vc view]];
If I call it, nothing happens. However, if I change it to:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
//[self.navigationController presentModalViewController:vc animated:YES];
[self setView:[vc view]];
The view appears just fine (without the transition, of course).
What am I doing wrong? Is there anything special you have to take care of when initializing the view controller? I tried to copy as much as possible from Apple's examples, but I can't get this to work...
Thanks for any input!
-- Ry
You can only present modal view controllers from controllers that have already been shown onscreen (usually through a UINavigationController or UITabBarController). Try creating a UINavigationController, pushing a viewController to it, and then presenting your modal controller. There's a starter project in Xcode that shows how to create a UINavigationController-based flow if you're unfamiliar with it.
One other thing to note: if you haven't pushed the view controller onto a UINavigationController, the .navigationController property will be nil, and messaging it will have no effect.
I encountered the same problem while attempting to show a modal view over another modal view. Ben's answer is correct, and can be implemented like so:
#interface FirstView: UIViewController {
UIViewController *firstView;
}
- (IBAction)showOptionsView:(id)sender;
#end
In the main view class:
- (void)viewDidLoad {
[super viewDidLoad];
firstView = [[UIViewController alloc]init];
[firstView setView:self.view];
[firstView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
}
- (IBAction)showOptionsView:(id)sender {
OptionsView *optView = [[OptionsView alloc]initWithNibName:#"OptionsView" bundle:nil];
if(firstView != nil) {
[firstView presentModalViewController:optView animated:YES];
[optView release];
}