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

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

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.

Can't Resize UIViewController After Presenting Over UITabBarController

I've got a UIViewController that I would like to display over top of my UITabBarController kind of like a custom UIAlertView. The problem is that, when I present the UIViewController, I'm unable to resize its view to fit whatever screen is currently being used. The UIViewController (ShareViewController is its name) is designed using a .xib file, and it's currently using iPhone 5 screen height. I basically just want to resize its UIView (view) if the app is being run on any device, but it won't work when I call setFrame.
Here is some code:
ShareViewController * svc = [[ShareViewController alloc] initWithNibName:#"ShareViewController" bundle:nil];
self.tabBarController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.tabBarController presentViewController:svc animated:NO completion:nil];
[svc.view setFrame:[[UIScreen mainScreen] applicationFrame]];
I use the "UIModalPresentationCurrentContext" setting so I can show the ShareViewController with a transparent background. So, when I run this code the ShareViewController just gets added but goes off screen because it is still at the iPhone 5 display height.
What can I do to resize my ShareViewController's main view?
Instead of presentviewcontroller better make it as addsubview and apply animation like present modal view controller
I gave the group of buttons a container which I then translated upwards depending on the screen center. This is a bit of a hack fix but I think there is a better way to implement this custom UIViewController anyway.

Prevent clicks on view that presented another view via UIModalPresentationFormSheet

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.

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.

creating button for popover view anchor at run time

This may not be possible, but I'm hoping someone will have an idea how to do it.
I have an app I'm porting from iPhone only to Universal. On the iPhone, I'm using a Tabbed application. I use three tabs for the normal data to be displayed. I have a forth tab that's only displayed if certain conditions are met. To add the tab, I do:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
UITabBarController *tabController = (UITabBarController *) self.rootViewController;
NSMutableArray* newArray = [NSMutableArray arrayWithArray: tabController.viewControllers];
[newArray addObject: [theStoryboard instantiateViewControllerWithIdentifier: #"AdditionalView-Phone"]];
[tabController setViewControllers:newArray animated:YES];
}
For the iPad, I have enough space on the initial view to display everything from the main three tabs in the iPhone UI. So all I need is one additional (small) view for the "Additional" data. I wanted to do it using a popOver view, so I set up the initial view with a Nav bar and popover button as in the Utility App template. But now I'm stuck. I can't figure out how to create that popover button at run time and make it do the segue to the popOver view properly. I can add the button like this:
UIBarButtonItem *flipButton = [[UIBarButtonItem alloc] initWithTitle: #"Modem" style: UIBarButtonItemStylePlain target: self action: #selector(togglePopover:)];
self.navBar.topItem.rightBarButtonItem = flipButton;
but I get an exception: 'NSInternalInconsistencyException', reason: 'UIStoryboardPopoverSegue must be presented from a bar button item or a view.' I'm pretty sure this is because I don't have an anchor set for the popOver segue. The button doesn't exist in the storyboard, so I can't set it there. And I can't seem to find an API to set it at run time.
I also tried creating the button in IB, but not in the view hierarchy, and then just setting the rightBarButtonItem property to my existing button. That also works, but I still can't set that button as the anchor for the popover view. I can set the Navigation Bar as the anchor, but that makes it anchor to the title in the nav bar, which looks silly.
Any ideas?
I had the same problem and solved it by creating a UIBarButtonItem in the Storyboard for the view controller but not part of the view hierarchy.
In IB, Drag a bar button item to the dark bar below the view controller view, drop it next to the "First Responder" and "View Controller" icons. Create a (strong) IBOutlet for it. Then create a popover segue from it to the destination view controller by dragging from the bar button item to the destination. It seems like this is the only way to set it as the anchor. Choosing it as the anchor for an existing segue does not work (looks like an IB bug).
In viewDidLoad you can assign this bar button item to the navigationItem (or where ever you like) and the segue works as expected.
I was curious about this too so I made a quick test project. You're right, there doesn't seem to be a way to configure the popover segue at runtime or add an anchor point to a button that's not in the view hierarchy using Interface Builder.
My solution was to set everything up in IB with the UIBarButtonItem visible and connected to an IBOutlet property, then remove it from the navigation bar in -viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = nil;
}
Then I simply add it back or remove it by tapping another button:
- (IBAction)toggleBarButtonItem:(id)sender
{
UIBarButtonItem *item = (self.navigationItem.rightBarButtonItem == nil) ? self.popoverBarButtonItem : nil;
[self.navigationItem setRightBarButtonItem:item animated:YES];
}
You could conditionally keep or remove the button in -viewDidLoad the same way. The segue remains anchored to the UIBarButtonItem.
I'm gonna try making a dummy view that's the size and shape of the views I want to present the popover from, wire that to the segue popover target, and then move the view to the right position in prepareForSegue:sender:
I'm not sure this is exactly what you want, but this is what I would do. Create a button and set it up with some target/action. Call that target/action method
presentPopover:(UIButton *)sender;
Then in the presentPopover method, say
UIViewController *customAdditionalViewController = [[MySpecialVC alloc] init];
//Configure the customAdditionalViewController
//Present the customAdditionalViewController in a Popover
UIPopoverController *popover = [[UIPopoverController alloc] initWithViewController:customAdditionalViewController];
//Set popover configurations
[popover presentPopoverFromRect:sender.frame inView:self.view permittedArrowDirections:/*whatever you want*/ animated:YES];
That is how I would handle your use case.

Resources