UIPopoverController alternative on iphone devices - ios

I have been searching for almost 2 hours on how to implement UIPopoverController in swift language, at the end, i found out that this api are exclusive for iPad devices only.
How will i be able to make a drop down list on iPhone devices?
please someone help me, at lease with the name of the api so that i know what to search for

You can you third party libraries for that:
FPPopover
WEPopover
or if you don't need iOS 7 support you can use iOS 8 new API which answered in this question
UIPopoverPresentationController on iOS 8 iPhone

i depends on your needs. You can show UIPickerView, present an action sheet or segue to another VC and then go back - these are standard ways.

#property(nonatomic,retain) UIPopoverPresentationController *popoverPresentationController;
- (IBAction)showPopover:(id)sender {
UIViewController *popoverViewController = [[UIViewController alloc] initWithNibName:#"NameViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:popoverViewController];
popoverViewController.preferredContentSize = CGSizeMake(280, 200);
navigationController.modalPresentationStyle = UIModalPresentationPopover;
_popoverPresentationController = navigationController.popoverPresentationController;
_popoverPresentationController.delegate = self;
_popoverPresentationController.sourceView = self.view;
_popoverPresentationController.sourceRect = [sender frame];
navigationController.modalPresentationStyle = UIModalPresentationPopover;
navigationController.navigationBarHidden = YES;
[_viewController presentViewController:navigationController animated:YES completion:nil];
}

Related

UIPopoverPresentationController is showing full screen modal on iPhone

On iPad UIPopoverPresentationController working fine but on iPhone it is always showing full window modal popup. i am using following code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MySecondViewController *contentVC = [storyboard instantiateViewControllerWithIdentifier:#"Pop"];
contentVC.modalPresentationStyle = UINavigationControllerOperationPop; // 13
UIPopoverPresentationController *popPC = contentVC.popoverPresentationController; // 14
contentVC.popoverPresentationController.sourceRect =CGRectMake(100, 130, 280, 230);
self.navigationController.preferredContentSize = CGSizeMake(200, self.parentViewController.childViewControllers.lastObject.preferredContentSize.height-100);
//self.showPop.frame; // 15
contentVC.popoverPresentationController.sourceView =
self.showPop; // 16
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny; // 17
popPC.delegate = self; //18
[self presentViewController:contentVC animated:YES completion:nil];
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
In ViewController.h Firstly make a property of UIPopoverPresenatationController.
#property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;
Then to show PopOverPresentationcontroller
UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
dateVC.preferredContentSize = CGSizeMake(280,200);
destNav.modalPresentationStyle = UIModalPresentationPopover;
_dateTimePopover8 = destNav.popoverPresentationController;
_dateTimePopover8.delegate = self;
_dateTimePopover8.sourceView = self.view;
_dateTimePopover8.sourceRect = [sender frame];
destNav.modalPresentationStyle = UIModalPresentationPopover;
destNav.navigationBarHidden = YES;
[self presentViewController:destNav animated:YES completion:nil];
You must have noticed that we are presenting View Controller instead of presenting popOver.So we have to hide this in new way also.It hides automatically when we click on screen.
-(void)hideIOS8PopOver
{
[self dismissViewControllerAnimated:YES completion:nil];
}
We have to implement the delegate of UIPopoverPresenatationController in implementation file.Write below delegate method in implementation file.
- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
return UIModalPresentationNone;
}
Popover controllers are for use exclusively on iPad devices.
Edit: As stated by Soberman, since iOS 8 it is possible to present popovers on iPhone using public APIs, so this answer is probably not relevant anymore.
As stated in Apple's documentation on UIPopoverController:
Popover controllers are for use exclusively on iPad devices.
So there is no way to use this class in iPhone application unfortunately. But there are a couple of custom third-party implementations of the functionality provided by UIPopoverController which add iPhone support and more. See https://github.com/50pixels/FPPopover for example.
Edit: There also is another highly customizable popover implementation for both iPhone/iPad worth checking out: https://github.com/nicolaschengdev/WYPopoverController.

IOS AdaptiveView Popover and NavigationController: how do they work?

I am updating an old app to the new adaptive size way of doing things and having difficulty getting a popover with a navigation controller to work.
My goal: I want to be able to open a popover from a button when the app is either compact and regular horizontal. The popover has a tableview and uses a navigation controller to push view controllers when the user touches a row on the table. I can get the popover to open correctly, but I can’t figure out who to make the pushes work.
Here’s the code that opens the popover:
OptionsController *vc = [[OptionsController alloc] initWithNibName:#"OptionsView" bundle:nil];
vc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popover = [vc popoverPresentationController];
popover.delegate = self;
[self presentViewController:vc animated: YES completion: nil];
popover.permittedArrowDirections = UIPopoverArrowDirectionUp; // change as necessary
popover.sourceView = self.view;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popover.sourceRect = popoverRect;
This code correctly opens a popover in either compact or regular size.
In the OptionsController’s didSelectRowAtIndexPath method, I have this(controllersArray is an array of UIViewControllers, each of which corresponds to a row in the table):
UIViewController *nextController = [self.controllersArray objectAtIndex: [indexPath row]];
[self.navigationController pushViewController:nextController animated:YES];
All this executes, but no push occurs, so the next view never appears.
I clearly am not understanding something about using the UIViewController’s navigationController, or how to install a navigationController to make this work. After three or four days of digging around to try to understand how to make this work, I'd appreciate any insights, or links to documentation about how to do this. Thanks in advance.
Crud - this has a very easy answer. Just took me thinking a different way and digging through Larcerax's comments. Here's how to make this work:
OptionsController *vc = [[OptionsController alloc] initWithStyle:UITableViewStylePlain];
vc.title = #"Options";
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController: vc];
nc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popover = [nc popoverPresentationController];
popover.delegate = self;
[self presentViewController:nc animated: YES completion: nil];
popover.permittedArrowDirections = UIPopoverArrowDirectionUp; // change as necessary
popover.sourceView = self.view;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popover.sourceRect = popoverRect;
The difference is that I create the UINavigationController in the usual manner...
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController: vc];
...set the navigationController's presentation style to popover, then get the popoverPresentationController from the navigationController - before I was doing those two methods on the UIViewController.
nc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popover = [nc popoverPresentationController];
Finally, I present the navigationController:
nc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popover = [nc popoverPresentationController];
This approach presents a popover, in compact and regular horizontal sizes, that contains navigation controller functionality: just what I wanted.
Thanks again to Larcerax whose answer wasn't what I needed, but made me re-think what I was doing in a different way. As usual, StackOverflow comes through.
Here's what you should try. I use about 10-40 navigation controllers per app for the apps I work on and I've had this same sort of issue, I've not used popovers, but I've subclassed the crap out of navigation controllers and view controllers to have encountered your same problem. The thing is that if you do this:
UIViewController * ff = [UIViewController new]
[self presnetViewController:ff ... blah blah blah
There is apparently NO navigation system attached to the modal view controller and therefore you can't navigate to anything else, you can only close the modal and move on. So, this is what I do to resolve this and it works everytime, well it works everytime for UIViewControllers, give it a shot
see the following, it's not for popovers, but the principle is the same:
NSHTermsOfServiceViewController * pvc = [NSHTermsOfServiceViewController new];
UIBarButtonItem * backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"exit-button"] style:UIBarButtonItemStylePlain target:self action:#selector(backerPressed)];
NSHNavigationController * ssf = [[NSHNavigationController alloc] initWithRootViewController:pvc];
[[pvc navigationItem] setLeftBarButtonItem:backBarButtonItem];
[[self navigationController] presentViewController:ssf animated:true completion:nil];
NSHTermsOfServiceViewController <== is a subclass of another subclass of a UIViewcontroller, it's basically a UIViewController on steroids, that's all
NSHNavigationController is a UINavigationController that is subclassed and pumped up on steroids for animations
The flow is this:
create a viewController
create a new UINavigationController
Set the view controller you created in step 1 as the root view controller of the navigation controller created in step 2
present the NAVIGATION CONTROLLER, not the UIViewController, you can present this navigationController from a view controller like so ..
v
[self presentViewController:ssf animated:true completion:nil];
or you can present it from the current view controller's navigation controller which is what I prefer, like so:
[[self navigationController] presentViewController:ssf animated:true completion:nil];
Your code, modified, the only problem is that I don't know if you can present a UIPopOverViewController by rooting it inside a navigation controller
OptionsController *vc = [[OptionsController alloc] initWithNibName:#"OptionsView" bundle:nil];
UIPopoverPresentationController *popover = [vc popoverPresentationController];
UINavigationController * stuff = [[NSHNavigationController alloc] initWithRootViewController:popover];
stuff.modalPresentationStyle = UIModalPresentationPopover;
stuff.delegate = self;
[self.navigationController presentViewController:stuff animated: YES completion: nil];
popover.permittedArrowDirections = UIPopoverArrowDirectionUp; // change as necessary
popover.sourceView = self.view;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popover.sourceRect = popoverRect;
Yep, my bad, doesn't work for popover, I just tried it
So, with that said, is it absolutely necessary to use a popover? Why are you using this and now just a UIViewcontroller that you reconfigure to look like a popover and then you have what you need?
Here's this, I just tried it with the Ipad simulator, and it allowed a push, just as it should have.
NSHLoginViewController * pvc = [NSHLoginViewController new];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:pvc];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
UIView * stuff = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 1000, 1000)];
[self.view addSubview:stuff];
[popover presentPopoverFromRect:[[self contentView] nameField].frame inView:stuff permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
this: [[self contentView] nameField].frame is just a uitextfield, nothing special, that's all, and the method above presented the login viewcontroller, when I put in my credentials, I pressed log in and it pusehed the next viewcontroller as it normally would, there's probalby something wrong with the touches being intercepted by your uitableview or whatever, perhaps not, but this method did work for me.

Display UIActionSheet in iphone the same as ipad

I have a a UIButton, and I would like to add a UIActionSheet.
How can I make the iphone version look like so:
If there is a way of doing it another way, meaning not with UIActionSheet, I'm open to hear other ways.
Hope I was clear enough. If you have questions, please feel free to ask.
You can do this in a native way in iOS8 only with the following
UIPopoverPresentationController *popOverController = [[UIPopoverPresentationController alloc] init];
popOverController.popoverContentSize = CGSizeMake(150, 160);
[popOverController setDelegate:self];
popOverController.sourceView = self.view;
popOverController.sourceRect = sender.frame;
popOverController.permittedArrowDirections = UIPopoverArrowDirectionUp;
[self presentViewController:popOverController
animated:YES
completion:nil];
you can use one of custom controls from cocoacontrols for iOS7 support
Good luck

UIPopoverController displayed as modalViewController in iOS 8

I just ran into a very frustrating problem. I don't know if it's an iOS8 bug or it's something else.
I'm loading the view from a nib, which looks like this:
Here ist my code:
UIViewController *popoverViewController = [[UIViewController alloc] init];
[popoverViewController setView:poppverViewFromNib];
_popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
[_popverController presentPopoverFromRect:CGRectMake(100, 100, 10, 10) inView:[self view] permittedArrowDirections:UIPopverArrowDirectionAny animated:YES];
The iOS simulator as well as the real device are displaying the viewController modally like you can see here:
EDIT
As requested in comments, I tell you what I expect when using UIPopoverController:
I expect an UIPopover, not a modalViewController.
So here my question to all of those how didn't get it: Why does my UIPopoverController does not display as a popover but as modalViewController? How can I fix it?
Read the documentation. Popover presentation is only available for horizontally regular size classes. Currently, this is only on iPad. Popover presentation on iPhone will always be executed as full screen modal presentation. See here.
You are lucky that iOS8 doesn't crash, as iOS7 and below, if you used UIPopoverController on a phone idiom, your app would crash. UIPopoverController is deprecated in iOS8 in favor of popover modal presentation. This is why your app does not crash.
You could keep the same code for UIPopoverController as iOS 7
just set ViewController.preferredContentSize = CGSizeMake(300, 290);
It will work.
Other Solution
iOS 8 has a new PopOverController called UIPopoverPresentationController
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navController = [storyboard instantiateViewControllerWithIdentifier:#"Terms_NC"];
navController.preferredContentSize = CGSizeMake(300, 290);
// Present the view controller using the popover style.
navController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:navController animated: YES completion: nil];
// Get the popover presentation controller and configure it.
UIPopoverPresentationController *presentationController =
[navController popoverPresentationController];
presentationController.permittedArrowDirections =0;
presentationController.sourceView = self.view;
presentationController.sourceRect = CGRectMake(100, 100, 300, 340);

What kind of popover on iPad

The iPad app pdf expert displays popovers which seem to consist only of the header. Which kind of popover is this? I can't find something about it in the Apple docs. But it seems to be a standard UI element. Or is it a custom view?
Its nothing like a custom view. Its just without UINavigationController.
ViewController *viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UIPopoverController * popover = [[UIPopoverController alloc] initWithContentViewController:viewController];
popover.delegate = self;
popover.popoverContentSize = CGSizeMake(644, 425);
[popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections: UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionUp animated:YES];
This will solve you problem. Check it out.!!

Resources