Transparent Modal View on Navigation Controller - iphone

I'm trying to create a transparent modal View on top of my navigation controller. Does anyone know if this is possible?

A modal view will cover the view it is pushed on top of as well as the navigation bar for your navigation controller. However, if you use the -presentModalViewController:animated: approach, then once the animation finishes the view just covered will actually disappear, which makes any transparency of your modal view pointless. (You can verify this by implementing the -viewWillDisappear: and -viewDidDisappear: methods in your root view controller).
You can add the modal view directly to the view hierarchy like so:
UIView *modalView =
[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
modalView.opaque = NO;
modalView.backgroundColor =
[[UIColor blackColor] colorWithAlphaComponent:0.5f];
UILabel *label = [[[UILabel alloc] init] autorelease];
label.text = #"Modal View";
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[label sizeToFit];
[label setCenter:CGPointMake(modalView.frame.size.width / 2,
modalView.frame.size.height / 2)];
[modalView addSubview:label];
[self.view addSubview:modalView];
Adding the modalView as a subview to the root view like this will not actually cover the navigation bar, but it will cover the entire view below it. I tried playing around with the origin of the frame used to init the modalView, but negative values cause it to not display. The best method that I found to cover the entire screen besides the status bar is to add the modalView as a subview of the window itself:
TransparentModalViewAppDelegate *delegate = (TransparentModalViewAppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.window addSubview:modalView];

The easiest way is to use modalPresentationStyle property of navigationController (but you'll have to make animation by yourself):
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalViewController animated:NO];
modalViewController.view.alpha = 0;
[UIView animateWithDuration:0.5 animations:^{
modalViewController.view.alpha = 1;
}];

I accomplish this most easily by setting up an "OverlayViewController" that sits above all other subviews of my window or root view. Set this up in your app delegate or root view controller, and make OverlayViewController a singleton so that it can be accessed from anywhere in your code or view controller hierarchy. You can then call methods to show modal views, show activity indicators, etc, whenever you need to, and they can potentially cover any tab bars or navigation controllers.
Sample code for root view controller:
- (void)viewDidLoad {
OverlayViewController *o = [OverlayViewController sharedOverlayViewController];
[self.view addSubview:o.view];
}
Sample code you might use to display your modal view:
[[OverlayViewController sharedOverlayViewController] presentModalViewController:myModalViewController animated:YES];
I haven't actually used -presentModalViewController:animated: with my OverlayViewController but I expect this would work just fine.
See also: What does your Objective-C singleton look like?

I had this same problem and in order to The solution is to add the modal view with addSubview: and animate the change in the view hierarchy with UIView’s animateWithDuration:delay:options:animations:completion:
I added a property and 2 methods to a subclass of UIViewController (FRRViewController) that includes other functionalities. I will be publishing the whole stuff on gitHub soon, but until then you can see the relevant code below. For more info, you can check my blog: How to display a transparent modal view controller.
#pragma mark - Transparent Modal View
-(void) presentTransparentModalViewController: (UIViewController *) aViewController
animated: (BOOL) isAnimated
withAlpha: (CGFloat) anAlpha{
self.transparentModalViewController = aViewController;
UIView *view = aViewController.view;
view.opaque = NO;
view.alpha = anAlpha;
[view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIView *each = obj;
each.opaque = NO;
each.alpha = anAlpha;
}];
if (isAnimated) {
//Animated
CGRect mainrect = [[UIScreen mainScreen] bounds];
CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
[self.view addSubview:view];
view.frame = newRect;
[UIView animateWithDuration:0.8
animations:^{
view.frame = mainrect;
} completion:^(BOOL finished) {
//nop
}];
}else{
view.frame = [[UIScreen mainScreen] bounds];
[self.view addSubview:view];
}
}
-(void) dismissTransparentModalViewControllerAnimated:(BOOL) animated{
if (animated) {
CGRect mainrect = [[UIScreen mainScreen] bounds];
CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
[UIView animateWithDuration:0.8
animations:^{
self.transparentModalViewController.view.frame = newRect;
} completion:^(BOOL finished) {
[self.transparentModalViewController.view removeFromSuperview];
self.transparentModalViewController = nil;
}];
}
}

Here's what I did to solve the problem - Google the details but this approach worked very well for me:
Take a screenshot of the underlying view. https://devforums.apple.com/message/266836 - this leads to a ready-made method that returns a UIView for the current screen.
Hand the screenshot to the modal view (I used a property)
Present the modal view
In the modal view controller's viewDidAppear, set the image as UIImageView at index 0. Adjust the vertical position of the image by the height of the status bar.
In the modal view controller's viewWillDisappear, remove the image again
The effect is:
The view animates in as any modal view does - the semi transparent parts of the modal view glide over the existing view
As soon as the animation stops, the background is set to the screenshot - this makes it appear as if the old view is still underneath even though it isn't.
As soon as the modal view's disappear animation starts, the image is removed. The OS meanwhile shows the old navigation view so the modal view transparently glides away and out of sight as you'd expect.
I tried animating in my own overlay view but it didn't work very well. I got a crash with no indication as to what has crashed. Rather than chase this down I did the bg view & Works really well.
Code in the modal view - I think you can figure out the rest, namely setting the property modalView.bgImage...
- (void)viewDidAppear:(BOOL)animated {
// background
// Get status bar frame dimensions
CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.bgImage];
imageView.tag = 5;
imageView.center = CGPointMake(imageView.center.x, imageView.center.y - statusBarRect.size.height);
[self.view insertSubview:imageView atIndex:0];
}
- (void)viewWillDisappear:(BOOL)animated {
[[self.view viewWithTag:5] removeFromSuperview];
}

self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:newview animated:YES];
and make sure you setup the modal view background to be transparent,
self.view.background = .... alpha:0.x;

if you set modalPresentationStyle for the modal view controller to:
viewController.modalPresentationStyle = 17;
The view in the background is not removed. (TWTweetComposeViewController use it).
I did not try to pass App Store review with this code though

This post about displaying a semi-transparent "Loading..." view might give a few pointers on how to proceed.

Yeah, you have to add the view manually, and if you want to slide in from the bottom or whatever you have to do the animation yourself too.
I wrote a class to do this, and a semi-modal datepicker using that class as an example.
You can find documentation in this blog post, the code is on github

I've been researching this same issue for the past week. I tried all the various answers and examples found in Google and here on StackOverflow. None of them worked that well.
Being new to iOS programming, I wasn't aware of something called UIActionSheet. So if you're trying to accomplish this in order to show a modal overlay of buttons (such as a modal asking someone how they want to share something), just use UIActionSheet.
Here is a webpage that shows an example of how to do this.

I got this idea from https://gist.github.com/1279713
Prepare:
In the modal view xib (or scene using storyboard), I setup the full-screen background UIImageView (hook it with the .h file and give it a property "backgroundImageView") with 0.3 alpha. And I set the view (UIView) background color as plain black.
Idea:
Then in "viewDidLoad" of the modal view controller I capture the screenshot from the original status and set that image to the background UIImageView. Set the initial Y point to -480 and let it slide to Y point 0 using 0.4-second duration with EaseInOut animation option. When we dismiss the view controller, just do the reverse thing.
Code for the Modal View Controller Class
.h file:
#property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView;
- (void) backgroundInitialize;
- (void) backgroundAnimateIn;
- (void) backgroundAnimateOut;
.m file:
- (void) backgroundInitialize{
UIGraphicsBeginImageContextWithOptions(((UIViewController *)delegate).view.window.frame.size, YES, 0.0);
[((UIViewController *)delegate).view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
backgroundImageView.image=screenshot;
}
- (void) backgroundAnimateIn{
CGRect backgroundImageViewRect = backgroundImageView.frame;
CGRect backgroundImageViewRectTemp = backgroundImageViewRect;
backgroundImageViewRectTemp.origin.y=-480;
backgroundImageView.frame=backgroundImageViewRectTemp;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
backgroundImageView.frame=backgroundImageViewRect;
} completion:^(BOOL finished) {
}];
}
- (void) backgroundAnimateOut{
CGRect backgroundImageViewRect = backgroundImageView.frame;
backgroundImageViewRect.origin.y-=480;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
backgroundImageView.frame=backgroundImageViewRect;
} completion:^(BOOL finished) {
}];
}
In viewDidLoad, simply call:
[self backgroundInitialize];
[self backgroundAnimateIn];
In anywhere we dismiss the modal view controller, we call:
[self backgroundAnimateOut];
Please note that this will ALWAYS animate the background image. So if this modal view controller transition style (or the segue transition style) is not set to "Cover Vertical", you may not need to call the animation methods.

I finally accomplished this, for a navigation or tab bar interface, by combining an overlay view controller (see: pix0r's answer) that's hidden / un-hidden before hiding or showing a view controller based on this very good blog post.
Concerning the view controller, the tip is to make its background view the clearColor, then the semi-transparent overlay view is visible and whatever views are added as subviews in the view controller are in front and most importantly opaque.

I've created open soruce library MZFormSheetController to present modal form sheet on additional UIWindow. You can use it to present transparency modal view controller, even adjust the size of the presented view controller.

For iOS 8+ you can use UIModalPresentationOverCurrentContext presentation style for presented view controller to easy achieve desired behavior.
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.9f];
viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:viewController animated:YES completion:nil];
If you also need to support iOS 7 - check this thread.

You can achieve transparent/semi-transparent modal view effect by overlaying a transparent/semi-transparent button on both the view and the navigation bar.
You can access the navigation bar through the navigationBar property of the UINavigationController.
I found that UIButton unlike UILabel will trap mouse events - hence giving the correct modal behavior.

I just found a workaround for that. Just create a 1X1 of UIViewController and add it to your parent view controller. And show the transparent modal view controller in that UIViewController.
on viewDidLoad;
self.dummyViewController = [[UIViewController alloc] init];
[self.dummyViewController.view setFrame:CGRectMake(0, 0, 1, 1)];
[self.view addSubView:self.dummyViewController.view];
when you need to open a transparentViewController;
[self.dummyViewController presentModalViewController:yourTransparentModalViewController animated:true];

If you need a screen like the attached one, the below code may help you.
The code:
MyViewController * myViewController = [[MyViewController alloc] initWithNibName:nibName bundle:nil];
UINavigationController * myNavigationController = [[UINavigationController alloc] initWithRootViewController: myViewController];
myNavigationController.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentModalViewController: myNavigationController animated:YES];

If say you want a screen overlay, use the parentViewController.view, it will place above navigation bar ++
MyCustomViewController* myOverlayView = [[MyCustomViewController alloc] init];
[self.parentViewController.view addSubview:myOverlayView];

This worked for me:
UIViewController *modalViewController = [[UIViewController alloc] init];
modalViewController.view.backgroundColor = [UIColor whiteColor] colorWithAlpha:0.5];
[self showDetailViewController:modalViewController sender:nil];

Related

Add a subview to MasterView of UISplitViewController

I need to add a subview to left part of UIViewController, which shows the user that there is something near the left part of screen, when masterview is hidden(in portrait orientation). And this view must move with left part of UISplitView. Something like the view with arrow in these two images. (Sorry for the russian interface)
http://s2.uploads.ru/8EHJI.png
http://s2.uploads.ru/NhEam.png
But my problem is that when I try to add such a view, it clips to bounds of masterview and is not visible when masterview is hidden. I think, I'm doing it wrong and there is an easy way to do this.
Update: I've tried to make some hack like:
-(void) clipToBoundsRecursive:(UIView *)someView
{
NSLog(#"%#", someView);
someView.clipsToBounds = NO;
for (UIView *v in someView.subviews)
{
[self clipToBoundsRecursive:v];
}
}
and send it to view of splitviewcontroller.
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
[self clipToBoundsRecursive:splitViewController.view];
It takes effect at first time (subviews outside the masterview's bounds shows, but after first show/hide animation they disappears and don't appear even if I call this method again)
You can add the view directly to the window's view, though you will have to manually manage its position depending on when the device rotates. Views added to the window.view will appear above the rootViewController.view.
I have described here a simple Logic for you: (how to add a UIView in Window and call it from your master or detail view )
Create UIView in #import "AppDelegate.h" ,
- (void) CreateViewInWindow
{
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 780)];// set as u wish
myView.backgroundColor = [UIColor redColor];
// I have added myView to the Window with a specific animation , your can give animation as you like. :)
[UIView transitionWithView:self.window duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve // change to whatever animation you like
animations:^ { [self.window addSubview:myView]; }
completion:nil];
}
Here create a simple UIButton in the DetailViewController.m file (You can put the code in either of the files, DetailViewController.m OR MasterViewController.m)
UIButton *btnShowView = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnShowView addTarget:self action:#selector(btnShowViewTapped:) forControlEvents:UIControlEventTouchUpInside];
btnShowView.frame = CGRectMake(20, 30, 174, 35);
//[btnLoginInner setBackgroundImage:[UIImage imageNamed:#"LoginBut.png"] forState:UIControlStateNormal];
[self.view addSubview:btnShowView];
In button tapped method, write code for calling UIView from AppDelegate, and also don't forget to add #import "AppDelegate.h" in DetailViewController.m,
-(void)btnShowViewTapped:(UIButton *) Sender
{
AppDelegate *del = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[del performSelector:#selector(CreateViewInWindow) withObject:nil afterDelay:0];
}
Above code is a simple logic for your problem, It might be helpful for you.
Sounds to me like your app could benefit from PKRevealController.
Try with deselecting auto layout option in identity and type pan if you are using nib otherwise set autoresizing mask to view that currently clipping. I believe it will solve the issue

How to replace UITableView within UIViewController on selection

I am coding in xCode 4.3
This is my first application.
I have a UIViewController, company logo on top, then search bar and then UITableView in the middle (with product names) and bottom footer image. Now I want that once an item is clicked on UITableView, only TableView is replace with a view showing product details.
Right now I can replace the entire view with following code:
if (!self.prodDetailViewController_)
{
self.prodDetailViewController_ = [[PCS1ProdDetailViewController alloc] initWithNibName:#"PCS1ProdDetailViewController" bundle:[NSBundle mainBundle]];
}
[self presentModalViewController:prodDetailViewController_ animated:YES];
But it just increases my work, because I will have to redo the top bar and bottom bar (which remains same in entire application) in all my views.
Is there a way that I just change the element of my main UIViewController to UITableView.
Thanking you in anticipation.
I'm going to assume you're able to use iOS 5 features here. What you can do is implement a container view controller - much like UINavigationController, but with your own view layout so you can keep logo, search bar, etc. all in place and only transition between views in a part of your view.
I created a new container view controller named ViewController. It has a UIView outlet containerView which is set up in the .xib file, along with a top bar, search bar, and bottom bar (corresponding to the other views you describe in your application). It also has properties tableViewController and detailViewController. In its viewDidLoad implementation, it adds a TableViewController instance as a child view controller. When the table view is tapped, the view controller adds a DetailViewController instance as a child view controller and transitions to it. Tapping a button on the detail view transitions back to the table view, and removes the detail view controller as a child.
Here's my viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableViewController = [[TableViewController alloc] init];
self.tableViewController.delegate = self; // I implement a protocol TableViewControllerDelegate to know when row is tapped
// Fix for origin being 20 by default.
CGRect frame = self.tableViewController.view.frame;
frame.origin.y = 0.0f;
self.tableViewController.view.frame = frame;
[self addChildViewController:self.tableViewController];
[self.containerView addSubview:self.tableViewController.view];
[self.tableViewController didMoveToParentViewController:self];
}
I have a delegate method so that the container knows when a table row is tapped, and does the transition between the table view and the detail view. Its implementation follows:
- (void)tableViewController:(TableViewController *)tvc didSelectIndex:(NSInteger)index
{
self.detailViewController = [[DetailViewController alloc] init];
self.detailViewController.backButtonBlock = [self backButtonBlock]; // This block handles the transiton from detail back to table
CGRect detailStartingFrame = self.detailViewController.view.frame;
detailStartingFrame.origin.x = self.containerView.frame.size.width;
self.detailViewController.view.frame = detailStartingFrame;
[self addChildViewController:self.detailViewController];
[self transitionFromViewController:self.tableViewController
toViewController:self.detailViewController
duration:0.5
options:0
animations:^{
CGRect newTableFrame = self.tableViewController.view.frame;
newTableFrame.origin.x = (-1.0f * newTableFrame.size.width);
self.tableViewController.view.frame = newTableFrame;
[self.containerView addSubview:self.detailViewController.view];
CGRect newDetailFrame = self.detailViewController.view.frame;
newDetailFrame.origin.x = 0.0f;
self.detailViewController.view.frame = newDetailFrame;
} completion:^(BOOL finished) {
[self.detailViewController didMoveToParentViewController:self];
}];
}
As mentioned above, the detail view executes a block when tapping on a back button. I create this block in ViewController here:
- (GoBackButtonBlock)backButtonBlock
{
GoBackButtonBlock block = ^ {
[self.detailViewController willMoveToParentViewController:nil];
[self transitionFromViewController:self.detailViewController toViewController:self.tableViewController duration:0.5 options:0 animations:^{
CGRect newDetailFrame = self.detailViewController.view.frame;
newDetailFrame.origin.x = self.containerView.frame.size.width;
self.detailViewController.view.frame = newDetailFrame;
CGRect newTableFrame = self.tableViewController.view.frame;
newTableFrame.origin.x = 0.0f;
self.tableViewController.view.frame = newTableFrame;
} completion:^(BOOL finished) {
[self.detailViewController removeFromParentViewController];
[self.detailViewController.view removeFromSuperview];
}];
};
return [block copy];
}
That's about all there is to it. Be sure to read the "Implementing a Container View Controller" section of the UIViewController class reference for more details. Hope this helps!
Prepare all of your detail in a View, then add this view to the current screen. That's that.
in your "tableViewDidSelectRowAtIndex" method,On selection of row,just show the particular custom view (which contains details of selected row),and at that same time hide the table view,so u can have the view that u want. And make a back button on that custom view,and on that button action,hide your current view and show the tableview again.

resize view to the right height after adding it to a uinavigationcontroller

so i've go a uiviewcontroller (with its default view) that i created programmatically like
TestViewController *aVC = [[MJImageCropViewController alloc] init];
[[self navigationController] pushViewController:aVC animated:YES];
inside it there is something like this in the viewDidLoad
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
the problem is, that the height of the view of the pushedViewController remains 460px but visible is only 416px (because of the existing navigationController.
is there a way to let the uiview of the pushed viewcontroller resize the right way without setting explicit the frame to 416 (because of rotation and so on)?
You may want to try something like this in -viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
// Resize view to account for nav bar
CGFloat navBarHeight = self.navigationController.navigationBar.bounds.size.height;
CGRect frame = self.view.frame;
frame.size.height = frame.size.height - navBarHeight;
self.view.frame = frame;
}
My guess is that the view is being resized correctly, but it's subview's autoresizing masks are not set properly. Also, it makes a lot more sense to place the autoresize code you posted either in loadView (if you are creating the view programmatically) or in the XIB file.
Try to log out the view controller's frame at the end of viewDidLoad via
NSLog(#"%#",NSStringFromCGRect(self.view.frame));
And see what that tells you.

Creating a UITabBar With a Normal UIViewController(Not UITabBarController)

I have a UIViewController and I wish to place a simple UITabBar like the in the screenshot below: I don't want to use an UITabBarController. In fact, my original setup uses one, and it's easy as cake to get it to work.
However, the thing is I found out it's a bad idea to put UITabBarControllers inside Navigation Controllers, so I'm forced to refactor the hierarchy (so please don't suggest using one).
Given an UIViewController, how can I add an UITabBar on the bottom programatically? I got my UITabBarDelegate all setup to show a specific view when 1 of the tab bars is clicked, but the problem is when the view controller loads, no tab bar shows up! Here's my code to do that:
- (void) viewDidLoad {
...some initialization...
CGRect frame = CGRectMake(0, 431, 320, 49);
profileItem = [[UITabBarItem alloc] init];
profileItem.image = icon;
profileItem.title = #"Diet";
tabBar = [[UITabBar alloc] initWithFrame:frame];
NSArray* items = [[NSArray alloc] initWithObjects:profileItem, nil];
tabBar.items = items;
tabBar.delegate = self;
[tabBar setSelectedItem:[tabBar.items objectAtIndex:0]];
[self.view addSubview:tabBar];
[super viewDidLoad];
}
What am I missing here?
EDIT: Argh, I found out it has to do with the frame... Hmm.. what y-coordinate should I use if I have an existing navigation header on top?
You mention in your edit that you already determined that it has to do with the frame. Your problem may stem from the fact that your view's size in viewDidLoad isn't guaranteed to be the same is it will be when it eventually gets displayed. UIKit resizes the view to fit the context in which it's being displayed just before viewWillAppear:.
If you want to add the tab bar in viewDidLoad, then you should position it at the bottom of your view's frame by doing some math:
CGRect frame = CGRectMake(0, self.view.bounds.size.height - 49,
self.view.bounds.size.width, 49);
Then set an appropriate autoresizingMask so that it remains at the bottom even if UIKit resizes your view:
tabBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;

Transparent Background with a Modal UIViewController

I have a dilema, I want to present to the user a semi-transparent view.
I found out by experimenting that if I simply pushed the transparent view to the top of my NavigationController's stack, that it would not render the transparency level I wanted. So I decided to simply add the view as a subview of the current view at the top of the stack.
This solution works, the view below is still visible, and the View is 'semi-modal'. The problem is, if the parent view inherits from UITableViewController (as mine does), then the view I 'push' onto it, does not cover the navigation bar at the top.
I really don't want to get into a situation where I am forced to enable / disable controls on the navigation bar every time I push this view, so I was wondering, if anyone knew of any solutions that I could use so that the view I push onto the UITableViewController will actually 'push over' the navigation bar?
Funny, I was just doing the same thing yesterday. Unfortunately it seems to be impossible. Once the modal view controller is in place, the previous view becomes hidden.
See this previous question on the topic.
You can still use the view controller and NIB files you have set up - here's my sample code
- (void)showUpgrade {
[self.upgradeVC viewWillAppear:NO];
[self.view addSubview:self.upgradeVC.view];
[self.upgradeVC viewDidAppear:NO];
}
- (void)hideUpgrade {
[self.upgradeVC viewWillDisappear:NO];
[self.upgradeVC.view removeFromSuperview];
[self.upgradeVC viewDidDisappear:NO];
}
- (UpgradeViewController *)upgradeVC {
if (_upgradeVC == nil) {
_upgradeVC = [[UpgradeViewController alloc] initWithNibName:[NSString stringWithFormat:#"UpgradeView_%#", self.deviceType] bundle:nil];
_upgradeVC.delegate = self;
}
return _upgradeVC;
}
You will need to store a reference to the parent view controller in the modal view controller so that you can access the -hide method. I did this through a delegate.
It would also be easy to add some animation to -show and -hide if you want it to animate up from the bottom of the screen - I was just too lazy to do this.
iOS 8 added the UIModalPresentationOverFullScreen presentation style. Set this as the presented view controller’s modalPresentationStyle. For more advanced needs, look into creating a custom presentation controller.
There is now a way to achieve this using iOS7 custom transitions :
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 : http://www.doubleencore.com/2013/09/ios-7-custom-transitions/
Try this:
ViewController *vc = [[ViewController alloc] init];
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[self presentViewController:vc animated:YES completion:nil];
Have you tried looping over the Modal View Controller's subviews and setting the background color to clear for every view? This is a DFS recursive function.
- (void)setBackgroundToClearForView:(UIView *)view {
if ([view subviews]) {
for (UIView *subView in [view subviews]) {
[self setBackgroundToClearForView:subView];
}
}
if ([view respondsToSelector:#selector(setBackgroundColor:)]) {
[view performSelector:#selector(setBackgroundColor:)
withObject:[UIColor clearColor]];
}
}
To use it call:
[self setBackgroundToClearForView:self.view];
in viewDidLoad.
This will do the trick.. Try this one.
// for clear color or you can easily adjust the alpha here
YourVC *vc=[[YourVC alloc]initWithNibName:#"YourVC" bundle:nil] ;
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
So that the view will be full screen unlike UIModalPresentationFormSheet..