0

I have a tabbar app in which I need to show a popover from the tabBarItem by clicking on it. So, I in my appDelegate:

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        if (viewController == [self.objTabBarController.viewControllers objectAtIndex:2])
        {
            if (self.settingsPopover == nil) {
                UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main - iPad" bundle: nil];
                SettingsViewController *settingsController = [mainStoryboard instantiateViewControllerWithIdentifier: @"SettingsPopover"];
                UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingsController];
                self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
                self.settingsPopover.delegate = self;

                CGSize screenSize;
                if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown){
                    screenSize = CGSizeMake ([UIScreen mainScreen].applicationFrame.size.width, [UIScreen mainScreen].applicationFrame.size.height);
                } else {
                    screenSize = CGSizeMake ([UIScreen mainScreen].applicationFrame.size.height, [UIScreen mainScreen].applicationFrame.size.width);
                }
                NSLog(@"WIDTH = %f, HEIGHT = %f", screenSize.width, screenSize.height);
                screenSize.height -= 50;
                screenSize.width = screenSize.width / 2 + 105;

                CGRect rect = CGRectMake(screenSize.width, screenSize.height, 1, 1);

                [self.settingsPopover presentPopoverFromRect:rect inView:self.window.rootViewController.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
            } else {
                [self.settingsPopover dismissPopoverAnimated:NO];
                self.settingsPopover = nil;
            }

            return NO;
        }
    }
    return YES;
} 

So it displays correctly. But I need to redraw the popover after the change of the device orientation. For this purposes I made:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(handleDidChangeStatusBarOrientationNotification:)
                                                     name:UIApplicationDidChangeStatusBarOrientationNotification
                                                   object:nil];
}

- (void) handleDidChangeStatusBarOrientationNotification:(NSNotification *)notification;
{
    if (self.settingsPopover)
    {
        CGSize screenSize;
        if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown){
            screenSize = CGSizeMake ([UIScreen mainScreen].applicationFrame.size.width, [UIScreen mainScreen].applicationFrame.size.height);
        } else{
            screenSize = CGSizeMake ([UIScreen mainScreen].applicationFrame.size.height, [UIScreen mainScreen].applicationFrame.size.width);
        }
        NSLog(@"WIDTH = %f, HEIGHT = %f", screenSize.width, screenSize.height);
        screenSize.height -= 50;
        screenSize.width = screenSize.width / 2 + 105;

        CGRect rect = CGRectMake(screenSize.width, screenSize.height, 1, 1);
        [self.settingsPopover presentPopoverFromRect:rect inView:self.window.rootViewController.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
    }
}

So, the NSLog shows the correct screenSize after the changing the orientation but the popover shows in incorrect place. Can anyone help me to solve this?

ShurupuS
  • 2,923
  • 2
  • 24
  • 44
  • when changing orientation you hide popover and display after delay in view – NANNAV Dec 26 '13 at 11:46
  • 1
    You can refer to my answer at http://stackoverflow.com/questions/3008477/uipopover-and-orientation-change/20970049#20970049. It works for iOS 7.0 and later. – Nitin Gupta Jan 07 '14 at 11:18

2 Answers2

0

For that you have to close your Popover first and then show it again as I have done to solve my problem

Retro
  • 3,985
  • 2
  • 17
  • 41
  • Unfortunately I have a navigation controller as a content for the popoverController, so I want to save it after the orientation has been changed. Anyway, after adding a dismiss method - the popover is dismissing after changing the orientation and not presenting next. – ShurupuS Dec 26 '13 at 11:11
  • dismiss and set nil to popover object, then allocate it should work – Retro Dec 26 '13 at 11:43
  • I don't need to remove the popover - there is some values and user data in textfields - which should be saved. – ShurupuS Dec 26 '13 at 11:47
  • you can save the value into NSUserDefault and then get back when you show – Retro Dec 26 '13 at 12:19
0

In case anyone is looking for an answer in Swift 3...

1) Register for orientation change events.

    NotificationCenter.default.addObserver(self, selector: #selector(screenRotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)

2) Inside your view controller being presented as a popover...

    func screenRotated() {
        // Redraw the popover.
        DispatchQueue.main.async {
            self.preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: self.view.frame.height)
        }
    }
Justin Domnitz
  • 3,217
  • 27
  • 34