5

Keeping popover in open state. Then, when I try to switch to 2/3 screen mode and change the position of center BarButtonItem with fixed space BarButtonItem in viewWillTrainsition, my popover tool-tip moves to the previous location of barButtonItem.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    if (size.width>size.height) {
        _fixedSpace.width = 280;
    } else {
        _fixedSpace.width = 80;
    }
} completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {

}];}

enter image description here

Rajneesh071
  • 30,846
  • 15
  • 61
  • 74

3 Answers3

0

From iOS11, bar button item is using constraint instead of frames. So try giving a constraint to each bar button item. It might doesn't reflect visually but it plays a major role in producing this kind of issue.

Try using below code to set the constraint:

if #available(iOS 11.0, *)
{
  _fixedSpace.widthAnchor.constraint(equalToConstant: 280.0).isActive = true
}

Hope this helps!

torap
  • 656
  • 6
  • 15
  • There is no width anchor for barButton. – Rajneesh071 Jan 09 '18 at 11:49
  • My apologies, I had custom view which supports widthAnchor so thought it should work. Anyway give a try to this https://stackoverflow.com/questions/45544961/negative-spacer-for-uibarbuttonitem-in-navigation-bar-on-ios-11 – torap Jan 09 '18 at 17:05
0

I replicated same scenario and I found a fix for this as below:

[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    if (size.width > size.height) {
        fixedSpace.width = 280;
    } else {
        fixedSpace.width = 80;
    }
} completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    CGRect rect = [self.view convertRect:barBtn.frame fromView:barBtn];
    popover.sourceRect = rect;
}];

Try to reset the sourceRect property in the completion block.

Hope this is helpful!

Dharmesh Siddhpura
  • 1,610
  • 12
  • 22
0

As far as I understood your question I want to propose a simple solution for this :

I have took a Viewcontroller and PopoverView in storyboard. Viewcontroller will work as main view controller where as PopoverView will work to display as popover. (Caution : Don’t Forget to set Explicit Content Size for PopoverView in StoryBoard) for more reference you can see attached screen shot of my storyboard.

enter image description here

Here is sample source code of Viewcontroller in which you will find Popoverview position will change as per the right button frame change.

This code is developed using Objective C

ViewController.h

    //
    //  ViewController.h
    //  SOPopoverControllerDemo
    //
    //  Created by Test User on 08/01/18.
    //  Copyright © 2018 Test User All rights reserved.
    //

    #import <UIKit/UIKit.h>

    @interface ViewController : UIViewController


    @end

ViewController.m

    //
    //  ViewController.m
    //  SOPopoverControllerDemo
    //
    //  Created by Test User on 08/01/18.
    //  Copyright © 2018 Test User All rights reserved.
    //

    #import "ViewController.h"

    @interface ViewController () <UIPopoverPresentationControllerDelegate>

    @property (weak, nonatomic) IBOutlet UIBarButtonItem *leftToolBarBtn;
    @property (weak, nonatomic) IBOutlet UIBarButtonItem *rightToolBarBtn;
    @property (weak, nonatomic) IBOutlet UIBarButtonItem *flexibleBtn;
    @property (weak, nonatomic) IBOutlet UIToolbar *bottomToolBar;
    @property (weak,nonatomic) UIPopoverPresentationController *popOverController;


    @end



    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.

        if (self.view.frame.size.width > self.view.frame.size.height) {
            self.rightToolBarBtn.width = 200;
            self.leftToolBarBtn.width = 200;
        } else {
            self.rightToolBarBtn.width = 150;
            self.leftToolBarBtn.width = 150;
        }

    }

    - (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            if (size.width > size.height) {
                _rightToolBarBtn.width = 200;
                [self dismissViewControllerAnimated:true completion:nil];
                [self rightToolBarBtnTapped:_rightToolBarBtn];
            } else {
                _rightToolBarBtn.width = 150;
                [self dismissViewControllerAnimated:true completion:nil];
                [self rightToolBarBtnTapped:_rightToolBarBtn];
            }
        } completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {

        }];
    }

    - (IBAction)rightToolBarBtnTapped:(id)sender {


        //Grab the controller for popover
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"PopoverView"];

        if (self.view.frame.size.width > self.view.frame.size.height ) {
            controller.preferredContentSize = CGSizeMake(200, 100);
        } else {
            controller.preferredContentSize = CGSizeMake(150, 100);
        }


        controller.modalPresentationStyle = UIModalPresentationPopover;
        [self presentViewController:controller animated:YES completion:nil];

        // configure the Popover presentation controller
        _popOverController = [controller popoverPresentationController];
        _popOverController.delegate = self;
        _popOverController.permittedArrowDirections = UIPopoverArrowDirectionUp;
        _popOverController.barButtonItem = self.rightToolBarBtn;

        }


    //--------------------------------------------------
    #pragma mark ->  UIPopOverController Delegate
    //--------------------------------------------------

    - (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
        return YES;
    }

    - (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
        NSLog(@"Popover Did Dismissed");
    }


    @end

PopoverView.h

    //
    //  PopoverView.h
    //  SOPopoverControllerDemo
    //
    //  Created by Test User on 08/01/18.
    //  Copyright © 2018 Test User All rights reserved.
    //

    #import <UIKit/UIKit.h>

    @interface PopoverView : UIViewController

    @end

PopoverView.m

    //
    //  PopoverView.m
    //  SOPopoverControllerDemo
    //
    //  Created by Test User on 08/01/18.
    //  Copyright © 2018 Test User All rights reserved.
    //

    #import "PopoverView.h"

    @interface PopoverView ()

    @end

    @implementation PopoverView

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    @end