UIPopoverPresentationController should have a non-nil sourceView or barButtonItem set before the presentation occurs on iOS 9

Francis F picture Francis F · Mar 21, 2017 · Viewed 17.4k times · Source

I'm trying to show a popup using a custom UIPopoverPresentationController class. But it crashes with the error(<UIPopoverPresentationController: 0x7a772950>) should have a non-nil sourceView or barButtonItem set before the presentation occurs. Below is my button click code where the crash occurs.

- (IBAction)showPopup:(UIButton *)sender {
ViewController *contentViewController = [[ViewController alloc] init];

    contentViewController.preferredContentSize = CGSizeMake(200, 200);
    contentViewController.modalPresentationStyle = UIModalPresentationPopover;
    myPopoverController *popOver = [[myPopoverController alloc]initWithPresentedViewController:contentViewController presentingViewController:self andTintColor:[UIColor lightGrayColor]];

    popOver.delegate = self;
    popOver.permittedArrowDirections = UIPopoverArrowDirectionUp;
    popOver.sourceRect = sender.frame;
    popOver.sourceView = self.view;
    [self presentViewController:contentViewController animated: YES completion: nil];
}

Below is a sample of how my custom UIPopoverPresentationController looks like

myPopoverController.h file

@interface myPopoverController : UIPopoverPresentationController

@property (readonly) UIColor *tintColor;


-(instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController andTintColor:(UIColor *)aTintColor;

@end


myPopoverController.m file

//Some code for UIPopoverBackgroundView

-(instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController
{

    self = [self initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController andTintColor: [UIColor redColor]];

    return self;
}


-(instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController andTintColor:(UIColor *)aTintColor
{

    self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];

    if (!self) {
        return nil;
    }

    [super setPopoverBackgroundViewClass: [myPopoverControllerBackgroundView class]];
    tintColor = aTintColor;


    return self;
}

I don't have a barbutton but I'm setting the sourceView. Am I doing something wrong here? Appreciate your help

Answer

Martin picture Martin · Apr 7, 2017

You can create a popover presentation controller like this also and it may work

- (IBAction)showPopup:(UIButton *)sender {

ViewController *contentViewController = [[ViewController alloc] init];
    contentViewController.preferredContentSize = CGSizeMake(200, 200);
    contentViewController.modalPresentationStyle = UIModalPresentationPopover;

UIPopoverPresentationController *popoverpresentationController = contentViewController.popoverPresentationController;
    popoverpresentationController.delegate = self;
    popoverpresentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
    popoverpresentationController.sourceRect = sender.bounds;
    popoverpresentationController.sourceView = sender;
    [self presentViewController:contentViewController animated: YES completion: nil];
}