16

As titled, in iOS8, [UIPopoverController presentPopoverFromRect] does not work for [UIApplication sharedApplication].keyWindow any more. (It does work in iOS7)

I verified following codes:

TestViewController *test = [[TestViewController alloc] initWithNibName:nil bundle:nil];

if (testPopoverController == nil) {
    testPopoverController = [[UIPopoverController alloc] initWithContentViewController:test];
    testPopoverController.popoverContentSize = CGSizeMake(250, 95*5);


}

CGPoint point = [sender convertPoint:CGPointMake(0, 0) toView:nil];
CGRect rect = CGRectMake(point.x, point.y, 24, 24);

[testPopoverController presentPopoverFromRect:rect inView:[UIApplication sharedApplication].keyWindow permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
LiangWang
  • 8,038
  • 8
  • 41
  • 54

4 Answers4

3

The best solution I've come up with is to handle it conditionally. If on iOS 7, use the working code we had for presenting a UIPopoverController on the key window. If on iOS 8, use the following:

     viewController.modalPresentationStyle = UIModalPresentationPopover;
     UIPopoverPresentationController *presentationController = viewController.popoverPresentationController;
     [presentationController setDelegate:self];
     presentationController.permittedArrowDirections = 0;
     presentationController.sourceView = [[UIApplication sharedApplication] keyWindow];
     presentationController.sourceRect = [[UIApplication sharedApplication] keyWindow].bounds;

     [viewController setPreferredContentSize:CGSizeMake(320, 480)];
     [parentController presentViewController:viewController animated:YES completion:nil];

This ends up functioning identically to:

     self.popoverController = [[UIPopoverController alloc] initWithContentViewController:viewController];
     [self.popoverController setDelegate:self];
     [self.popoverController setPopoverContentSize:isLandscape() ? CGSizeMake(480*2, 320*2) : CGSizeMake(320*2, 480*2)];
     [self.padPopover presentPopoverFromRect:CGSizeMake(320, 480)
                                      inView:[[UIApplication sharedApplication] keyWindow]
                    permittedArrowDirections:0
                                    animated:YES];
Matt Foley
  • 921
  • 1
  • 8
  • 24
  • 1
    i tried out your solution, that dint work for me either .. there are no errors.Im able to display popovers in other views.But in this particular case I'm trying to show the popover no matter where the user is in the application. Thats why I'm using the key window and stuff.But no matter what i do the popover simply doesn't show up in iOS 8 – humblePilgrim Sep 29 '14 at 13:03
  • I'm using it in production code, not sure why it's not working for you, sorry! – Matt Foley Sep 29 '14 at 13:49
  • Looks like a combination of the above solution and http://stackoverflow.com/questions/24854802/presenting-a-view-controller-modally-from-an-action-sheets-delegate-in-ios8-ios has provided me the solution. Thanks for the solution. – ponnu Aug 18 '15 at 01:05
1

Change the inView parameter in

[testPopoverController presentPopoverFromRect:rect inView:[UIApplication sharedApplication].keyWindow permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];

to

[testPopoverController presentPopoverFromRect:rect inView:"your current View Controller's view" permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];

And make sure it is in dispatch block

  dispatch_async(dispatch_get_main_queue(), ^{

});

Also kip changing your rect origin n size values if it is within the bounds

sheetal
  • 3,014
  • 2
  • 31
  • 45
  • This is exactly what I suggested before your post and I get a downvote for it... :( Smh. I'm just trying to help, no upvote is fine but I think a downvote is harsh for trying to help with a valid solution. – C0D3 Nov 20 '15 at 20:47
0

Try the solution found at this link: http://github.com/werner77/WEPopover

1st, let's do this code:

if ([viewController respondsToSelector:@selector(setPreferredContentSize:)]) {
    viewController.preferredContentSize = CGSizeMake(200, 300.0f);
} else {
    viewController.contentSizeForViewInPopover = CGSizeMake(200.0f, 300.0f);
}

self.popoverController = [[popoverClass alloc] initWithContentViewController:viewController];

if ([self.popoverController respondsToSelector:@selector(setContainerViewProperties:)]) {
    [self.popoverController setContainerViewProperties:[self improvedContainerViewProperties]];
}

self.popoverController.delegate = self;

[self.popoverController presentPopoverFromRect:[sender bounds]
      inView:sender
      permittedArrowDirections:UIPopoverArrowDirectionUp
      animated:YES];

I hope this helps. It was tested and works for iOS6-iOS8.

PS. Don't forget to check viewDidLoad, and give thanks to the WEPopover Library.

filoxo
  • 8,132
  • 3
  • 33
  • 38
Kabitis
  • 51
  • 7
-1

I think you have to display it in full view/viewcontroller and not in [UIApplication sharedApplication].keyWindow

So change this code:

[testPopoverController presentPopoverFromRect:rect inView:[UIApplication sharedApplication].keyWindow permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];

to:

[testPopoverController presentPopoverFromRect:rect inView:aViewControllerInYourApp permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
C0D3
  • 6,440
  • 8
  • 43
  • 67