Prevent clicks on view that presented another view via UIModalPresentationFormSheet - ios

I have a view that is presenting another view via
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[weakSelf presentViewController:navigationController animated:YES completion:^{}];
The only problem is that the "main" view that presented that new view, has buttons that can be touched because the ModalPresentationFormSheet doesn't take the full screen. I would like to keep that format, but prevent clicks while the Modal is being presented. I know I could do this this check on every possible buttons, but I am sure there is another way!
if (![weakSelf presentedViewController])
Thanks!

You can put the "new view" as a child view of another view that has full screen and make that "parent view" background color to clear color so you can see the "main view" also. Now you can't click the button cause you are actually clicking the view that is the parent on "new view"

One approach could be to place an invisible 'shield' above the hosting view controller, but below the form sheet.
Basically, create an empty UIView whose background color is clear. Add that as a subview to your presenting view controller just before you make your call:
[weakSelf presentViewController:navigationController animated:YES completion:^{}];
Now, this doesn't necessarily mean such a solution is in good taste. That is, the form sheet style isn't meant to be exclusive in that way, and it can be confusing if the UIView installed above is clear. So, you could reduce the alpha value on that view to turn it into a dimming screen, to help the user understand that the form sheet is the only thing they can interact with at that time:
UIView *dimmingScreen = [[UIView alloc] initWithFrame:self.view.bounds];
dimmingScreen.alpha = 0.5; // play with this value to get different degrees of dimming
dimmingScreen.backgroundColor = [UIColor blackColor]; // play with different colors
[self.view addSubview:dimmingScreen];
// Now present your form sheet, as you were:
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[weakSelf presentViewController:navigationController animated:YES completion:^{}];
You'll want to be able to remove the dimming screen too, so best make it a view controller property you can access so as to remove when needed.

Related

How to show one viewcontroller over other as overlay in iOS?

I have two view controller which Controller A and B. A controller displaying some info on screen. On top right of A screen I have a UIButton on click of button I want to show a help screen which will have some labels & when I touch the help screen it should go away.
I can do it by adding a view on top of all view & hide, show it. But I want to know how can I show HelpScreenViewController as a semitransparent view controller on top of first view controller on click of UIButton. When I tap on HelpScreenViewController it should go away.
EDIT:
I have added below code but does not work
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];
Thanks in advance.
For what you described, you dont need a ViewController to contain the 'TopOver' view. A normal UIView would be better. Place that within your first ViewController, in interface builder. Drag it into your A ViewController class, along with the button. When the button is clicked, just show/hide your view containing the info you need.
You can use the containerView control and you can add the childViewController for it. You can use this as overlay by doing the background colors transparent as your needs.
This article may help help you http://spin.atomicobject.com/2015/07/21/ios-container-views/
One more thing, you can set this containerview hide/visible as you need.

Page view controller inside Container presents View controller overtop UI

In my app, I have a nav bar and two toolbars visible in the main View Controller. I then have a container view in that main VC that fills the screen, behind the UI elements. I embedded a UIPageViewController in the container. I then set up a UICollectionViewController scene that is reused when swiping between the pages. This is done in code - see below. Basically, it presents the UICollectionViewController on screen.
It's working well, except when it appears on screen it covers up the UI of the main VC. I could change the height to reveal the UI, but I do want it to take up the entire screen. I just want it to lie behind the toolbars. That way when the user scrolls the Collection VC the content will be rendered underneath those translucent toolbars.
I understand why it's behaving the way it is, but I don't know how to fix it. I originally figured since it's all embedded in a Container it would respect the z-order of that container which appears fine in the storyboard, but I suppose if I'm just throwing the VC on screen in code I should expect such behavior. I'm just not sure how to get the desired behavior. Thanks for the assistance!
//the following code is in the main view controller
//set first page view controller
ContentCollectionViewController *startingViewController = [self viewControllerAtIndex:0]; //calls method below
[self.pageViewController setViewControllers:#[startingViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
//move page view controller down to reveal the underlying UI and show my issue
self.pageViewController.view.frame = CGRectMake(0, 80, self.view.frame.size.width, self.view.frame.size.height);
//display created page VC
[self addChildViewController:self.pageViewController];
[self.pageViewController didMoveToParentViewController:self];
[self.view addSubview:self.pageViewController.view];
//in the viewControllerAtIndex method:
ContentCollectionViewController *contentCollectionViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"ContentCollectionViewController"];
//set properties here...
return contentCollectionViewController;
I was finally able to solve it by changing
[self.view addSubview:self.pageViewController.view];
to
[self.view insertSubview:self.pageViewController.view atIndex:1];

How to create a popover coming from bottom of the screen for iPad

I am looking for a way to implement this kind of popover.
Are there basic iOS commands to generate this style instead of the usual Arrow + Border popover that we see in XCode? Or is there an API to do this kind of thing.
The popover is coming up from the bottom of the screen, just like in the App Store animation sometimes.
Thank you
What you want to do is create a custom UIVIewController with the modal presentation style set to UIModalPresentationFormSheet:
YourCustomViewController *customVC = [[YourCustomViewController alloc] initWithNib:#"YourCustomViewController" bundle:nil];
customVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self self presentViewController:customVC animated:YES completion:nil];
You will also have to create a toolbar and format it correctly with a "close" or "done" button that will dismiss the view controller

Programmably show UIViewController with transparent background [duplicate]

This question already has answers here:
Transparent Background with a Modal UIViewController
(6 answers)
Closed 9 years ago.
I am trying to display on the iPad a UIcontroller in my original viewcontorller, but smaller sized, so that the user is able to interact with it as well as with the contorller in the background. this was my aim but it is ok even if the user can't interact with the controller on the background, but it is essential to see the contorller in the background. I tried this code:
controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:controller animated:YES];
controller.view.layer.cornerRadius = 10; // this value vary as per your desire
controller.view.clipsToBounds = YES;
controller.view.frame = CGRectMake(343, 163, 316, 546.5);
This displays the controller with the set frame, but in the background you can't see the other controller, but just black. Why?
Definetely use this Presenting View Controllers from Other View Controllers and this About View Controllers
The section "Presentation Styles for Modal Views" says about your problem I think.
There are different presentation styles for controllers. You can set property - modalPresentationStyle to UIModalPresentationPageSheet or UIModalPresentationFormSheet that shows view controllers above other.
controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
controller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:controller animated:YES];
Another way is using UIPopoverController. It designed for showing views that sized not all the screen view. But the touches on other view controller will hide it.

Display Modal View Controller over detail view in UISplitViewController

I have a UISplitViewController in an iPad app. When something is selected from the table I want to fade in a modal view controller over the detail view. I can present it without a problem, but for some reason I can't get it to match the frame of the detail view. I would like it to stick to the detail view controller frame on rotation as well. Does anyone have any experience with this? This is my code to display. The detail view controller reference is set in the app delegate and passed down the table controllers.
QuestionViewController_iPad *questionView = [[[QuestionViewController_iPad alloc] initWithNibName:#"QuestionViewController_iPad" bundle:nil] autorelease];
questionView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
// Not quite
questionView.modalPresentationStyle = UIModalPresentationCurrentContext;
questionView.questionQuizCon = [QuestionQuizConnection firstQuestionForQuiz:quizCatCon.quiz];
// Maybe something like this?
[self.detailViewController presentModalViewController:questionView animated:YES];
When the modal view presents, it matches the size of the detail view controller, but it doesn't but it sits on the top left of the screen behind the master view controller. It also doesn't resize on rotation. I have the springs and struts set to auto size and fill. The height changes on rotation but it won't fill the width.
I couldn't get this to look right any way I tried it so I ended up just using view transitions to make it look like pages being torn off a notebook. That looks better anyway.
// Transition the view on as a subview.
[UIView transitionWithView:self.detailViewController.pageView duration:1.0
options:UIViewAnimationOptionTransitionCurlUp
animations:^ {
questionView.view.frame = CGRectMake(0, 0, self.detailViewController.pageView.frame.size.width, self.detailViewController.pageView.frame.size.height);
[self.detailViewController.pageView addSubview:questionView.view];
// Watch this one
self.detailViewController.currentQuestionViewController = questionView;
}
completion:nil];
After [self.detailViewController presentModalViewController:questionView animated:YES]; you should set center property and/or frame of questionView. Be sure that you set it after presenting modal view.

Resources