objective-cuipopoverpresentationcontroller

Old method of handling UIPopovers not working; copied code, now getting crash


**** UPDATE** getting the following crash: [UploadViewController _viewForPresenting]: unrecognized selector sent to instance 0x7abe4c00**

The old way of using UIPopOvers was deprecated in iOS 8; so I tried to upgrade; unfortunately it's not working. I don't get the popover per se, just the top of the current view at the bottom (see image here). I'm sure something is missing here, but after spending 2 days on it, I don't see the problem. I've been away from the coding effort, so I am requesting help in solving this coding issue. This is my code (copied and modified from here):

    //  make the popover
UIViewController * popoverContent = [UIViewController new];

UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 614, 804)];
popoverView.backgroundColor = [UIColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)1.0];  //  frame color?
popoverContent.view = popoverView;

//resize the popover view shown in the current view to the view's size
popoverContent.preferredContentSize = CGSizeMake(614, 804);

// NSString *urlAddress = @"https://google.com";
NSString *urlAddress = @"http://pragerphoneapps.com/upload-help/";
NSURL  *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];

//  add the UIWebView for RichText
UIWebView *webView = [[UIWebView alloc] initWithFrame: popoverView.frame];
webView.backgroundColor = [UIColor whiteColor];  //  change background color here

//  add the webView to the popover
[webView loadRequest:requestObj];
[popoverView addSubview:webView];

//create a popover controller
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"UploadViewController"];

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

//  configure the Popover presentation controller
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp; 

//  get warning on the following line: Incompatible pointer types assigning to 'UIBarButtonItem * _Nullable' from 'UploadViewController *'
popController.barButtonItem = self;

//  also get warning on the following line:  Assigning to 'id<UIPopoverPresentationControllerDelegate> _Nullable' from incompatible type 'UploadViewController *const __strong'  
popController.delegate = self;

popController.sourceView = popoverView;
popController.sourceRect = CGRectMake(10, 10, 614, 804);

Solution

  • Read the warning you're getting:

    //  get warning on the following line: Incompatible pointer types assigning to 'UIBarButtonItem * _Nullable' from 'UploadViewController *'
    popController.barButtonItem = self;
    

    UIPopoverPresentationController's barButtonItem property is supposed to be a UIBarButtonItem. You're setting it to your view controller, which isn't a UIBarButtonItem. The result is that UIKit tries to send messages to your view controller that UIBarButtonItem would be able to accept, but since your view controller isn't a UIBarButtonItem, it doesn't know how to handle those messages, and you crash.

    Also, fix this while you're at it:

    //  also get warning on the following line:  Assigning to 'id<UIPopoverPresentationControllerDelegate> _Nullable' from incompatible type 'UploadViewController *const __strong'  
    popController.delegate = self;
    

    This one's an easy fix; just make your UploadViewController class conform to the UIPopoverPresentationControllerDelegate protocol (and implement whatever methods you need to make it function properly as such).

    Tl;dr: Don't assign objects to properties of incompatible types. Also: When the compiler gives you a warning, it's trying to help ya ;-)