1
votes

I have a UIButton within a view. The UIButton is positioned like

enter image description here

I have an @IBAction that is triggered when a UIButton is clicked

@IBAction func shareButtonClicked(_ sender: AnyObject) {
    Flurry.logEvent("Share button tapped");


    let textToShare = quotetext.text 

    // 1.
    // Create and initialize a UIAlertController instance.
    //
    let alertController = UIAlertController(title: nil,
                                            message: nil,
                                            preferredStyle: .actionSheet)

    // 2.
    // Initialize the actions to show along with the alert.
    //
    let copyAction = UIAlertAction(title:"Copy Quote to clipboard",
                                   style: .default) { (action) -> Void in
                                    let pasteboard: UIPasteboard = UIPasteboard.general
                                    pasteboard.string = self.quotetext.text;
    }

    let defaultAction = UIAlertAction(title:"Share Quote",
                                      style: .default) { (action) -> Void in
                                        // We have contents so display the share sheet
                                        self.displayShareSheet(shareContent: textToShare)

    }

    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
        // ...
    }

    // 3.
    // Tell the alertController about the actions we want it
    // to present.
    //
    alertController.addAction(copyAction)
    alertController.addAction(defaultAction)
    alertController.addAction(cancelAction)


    // 4.
    // Present the alert controller and associated actions.
    //
    self.present(alertController, animated: true, completion: nil)

}

This produces an alert that looks like

enter image description here

When 'Share Quote' is selected, the alert brings up a shareSheet.

This @IBAction works on iPhone, but is crashing on the iPad. The error message is

'NSGenericException', reason: 'Your application has presented a UIAlertController () of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

I have tried to fix this problem by trying something like

    //iPad

    alertController.popoverPresentationController?.sourceView = viewBottom
    alertController.popoverPresentationController?.sourceRect = viewBottom.bounds
    alertController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down;

This fix does not work. The alert is positioned incorrectly over 'viewBottom' and when I click the 'defaultAction' button - it crashes again with the above error message.

I'm sort of at a loss here to fix this. Can anyone give some advice on this? I have tried various ways to use

the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

in my code, but wasn't successful. Any advice appreciated on this. Thanks.

1

1 Answers

2
votes

Replace these lines:

alertController.popoverPresentationController?.sourceView = viewBottom
alertController.popoverPresentationController?.sourceRect = viewBottom.bounds
alertController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down;

with:

if let button = sender as? UIButton {
    alertController.popoverPresentationController?.sourceView = button
    alertController.popoverPresentationController?.sourceRect = button.bounds
}

You must also property setup the popoverPresentationController of the share sheet in your displayShareSheet method. You should probably pass in the UIButton as a parameter to that method so you can use it there.