Why does UIPopoverPresentationController resize content?

I tried to expose the view controller to a popover using the old (iOS 7) and new (iOS 8) ways, but when my VC is presented in the popover it has extra space on the side because its frame size is wider when set to 13 pt. What for?

More details :

It looks great in the iOS7 simulator (when written the old way).

I figured out that 13 pt is probably the size of the arrow (when you press the up or down arrow, it adds 13 pt to the height instead of the width).

I did some additional testing (setting a breakpoint on setFrame:

my view) and found that there is a method UIPopoverPresentationController


that calls setFrame:

with a bad frame. After reading the UIPopoverPresentationController class reference, I learned that an instance of this class is instantiated and managed UIKit

when the popover is presented. So why UIKit

are you trying to resize my view to include an arrow?

For reference

By "old way" I mean that I override the contentSizeForViewInPopover

rendered view controller method and then render it with

self.popoverController = [[UIPopoverController alloc] initWithContentViewController:aViewController];
[self.popoverController presentPopoverFromRect:rect


By "new way" I mean

viewController.preferredContentSize = CGSizeMake(50.0f, 50.0f);
viewController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:viewController animated:YES completion:nil];

UIPopoverPresentationController *presentationController = [viewController popoverPresentationController];
presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight;
presentationController.sourceView = aSourceView;
presentationController.sourceRect = aFrame;


My current workaround

I do not allow resizing my view with UIPopoverPresentationController

or any controller.

@interface FixedSizeView : UIView

@implementation FixedSizeView {
    CGSize size;

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        size = frame.size;
    return self;

- (void)setFrame:(CGRect)frame {
    if (CGSizeEqualToSize(size, frame.size) || CGSizeEqualToSize(CGSizeZero,size)) {
        [super setFrame:frame];



source to share

All Articles