UIPopoverController placement - ios

I'm working on an app that is supposed to be universal, one app for both iPad and iPhone. I would like to keep their interfaces as similar as possible. In the iPhone app I am using a Tab bar controller, and one of those tabs goes to an image picker controller. Obviously I cannot do that in iPad. So I have hijacked control of that button to bring a popupcontroller that has the image picker in it. This all works well enough, except when I bring up the popup, it is not in the correct place. When I rotate the simulator, the popup goes to the correct place, and stays when I rotate back even.
My code is based on the code in this question:
Ipad UIImagePickerController and UIPopoverController error
Why would my popup not be in the correct location?

If your code is based on the question you referenced, it would appear you are using the following code to show the popover:
[popoverController presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES]
UIPopoverController:presentPopoverFromBarButtonItem:permittedArrowDirections:animated accepts a UIBarButtonItem* for the sender which your UITabBar does not have. UITabBar uses UITabBarItem which has a base of UIBarItem. UIBarButtonItem also has that base (UIBarItem).
Anyhow... I also needed to show a uipopovercontroller from a tabbaritem, I used the following code:
MyViewController *myVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:[NSBundle mainBundle]];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:myVC];
[myVC release];
popover.popoverContentSize = myVC.view.frame.size;
popover.delegate = self;
int tabBarItemWidth = self.tabBar.frame.size.width / [self.tabBar.items count];
int x = tabBarItemWidth * 6;
CGRect rect = CGRectMake(x, 0, tabBarItemWidth, self.tabBar.frame.size.height);
[popover presentPopoverFromRect:rect
inView:self.tabBar
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
Note: your x calculation will be different. The tab bar item selected for me was the 6th one.
Basically
x = tabBarItemWidth * currentTabBarItemIndex;

Related

Wrong Size-Class of UIViewController shown with UIPopoverController

I am working on universal iPhone/iPad application with universal storyboard. For some ViewControllers I'm using size classes if they has some specific layout on iPad.
I have one ViewController that needs to be presented modally on iPhone but on iPad it needs to be shown in UIPopoverController.
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:#"ComposeMessageNavigationController"];
ComposeMessageViewController *viewController = (ComposeMessageViewController *)navigationController.topViewController;
//Prepeare my view controlller
...
if (IS_IPAD) {
UIPopoverController * popover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGRect popoverFrame = CGRectMake(screenSize.width / 2, screenSize.height / 2, 1, 1);
[popover presentPopoverFromRect:popoverFrame inView:self.view permittedArrowDirections:0 animated:YES];
} else {
[self presentViewController:navigationController animated:YES completion:^{
}];
}
It works pretty good but there is problem with Size Classes. I made some changes on storyboard at wRegular/hRegular Size Class but on iPad in UIPopoverController still showing iPhone layout. It's because of size of popover is lower then iPad screen. Can I make my changes in Interface Builder with Size Classes to show them in popover on iPad but ignore on iPhone?
Using setOverrideTraitCollection on the popover view controller should allow you to use the regular x regular for an iPad.

UIPopover doesn't block UIBarbutton items from being pressed

I'm creating an app that has some UIBarButton items, some of which will launch a UIPopoverController when pressed. I'd like for this to disable anything from being able to be interacted with, which mostly happens by default. I've noticed, however, that other UIBarButtonItems within the same toolbar will still be active while the popover is active. I've tried to add:
[_popOver setPassthroughViews:nil];
prior to showing it, but the UIBarButtonItems are still able to be pressed while the pop over is shown. I realized I could disable the buttons, but I'd rather not have to do this as I'd have to introduce all kinds of unnecessary state while each kind of pop-over is open. Is there any way to have the pop-over be dismissed when anything is selected outside the pop-over (including other UIBarButtonItems)?
Basic code to repro the problem:
- (IBAction)rightButtonPressed:(id)sender {
UIViewController *vc = [[UIViewController alloc] init];
_popOver = [[UIPopoverController alloc] initWithContentViewController:vc];
[_popOver setPassthroughViews:nil];
[_popOver presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
- (IBAction)leftButtonPressed:(id)sender {
NSLog(#"Why am I active while pop-over is visible?");
}
Add both bar button items to the same navigation bar.
I'm an idiot, figured out the solution moments after posting this. It seems the call to presentPopoverFromBarButtonItem automatically adds the navigation bar to the passthroughviews. Since I was clearing out before and not after presenting the UIPopoverView, it was getting added back. A simple change of the order of the calls fixes the problem.
- (IBAction)rightButtonPressed:(id)sender {
UIViewController *vc = [[UIViewController alloc] init];
_popOver = [[UIPopoverController alloc] initWithContentViewController:vc];
[_popOver presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
//Call this *AFTER* presenting the popover
[_popOver setPassthroughViews:nil];
}

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);

Popover view controller not showing

I have a login view which I want to display in popover. I am doing this from code as below:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:[NSString stringWithFormat:#"MainStoryboard_%#", isIPAD ? #"iPad" : #"iPhone"] bundle:NULL];
UIViewController *navCtrl = [storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navCtrl];
popover = popover;
popover.delegate = self;
popover.popoverBackgroundViewClass = [PopoverBackground class];
self.popover = popover;
[self.popover presentPopoverFromRect:((UIButton *)sender).bounds
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionDown
animated:YES];
But the popover never shows. But the weird thing is viewdidload and viewwillappear for loginview are called. And on again clicking on the view calls the popover delegate method didDismissPopover.
Though it works fine when presented from a popover segue.
I do not want to create a segue because login might be called from different locations and I want to keep this code separate.
Has anyone before faced such issue.
Solved it!!
Turned out I was giving the arrow direction as UIPopoverArrowDirectionDown and the rect to show was not proper. Changed the rect to (100, 500, 10, 10), and voila! Everything is perfect.

PopoverView issue

i am first time using Popoverview, and i have one issue when i am using popover view.
here is the code which i am using it working fine
objManage = [[xyViewController alloc]init];
aPopover = [[UIPopoverController alloc] initWithContentViewController:objManage];
aPopover.delegate = self;
CGSize size = CGSizeMake(768,1004);
[aPopover setPopoverContentSize:size animated:YES];
CGRect rect = importAddress.frame; //CGRectMake(100.0f, 918, 768,900);
[aPopover presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
[objManage release];
So i am sucessfully open view controller in popoverview.
i have one button in xyViewController class, Ok suppose i click on button popover view dismiss, How can i dismiss popoverview in another class.
Thank you,
You want to call the method dismissPopoverAnimated:(BOOL)animated on the popover
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIPopoverController_class/Reference/Reference.html#//apple_ref/doc/uid/TP40009306-CH1-SW9

Resources