Presenting a Uialertcontroller Properly on an iPad Using iOS 8

Presenting a UIAlertController properly on an iPad using iOS 8

You can present a UIAlertController from a popover by using UIPopoverPresentationController.

In Obj-C:

UIViewController *self; // code assumes you're in a view controller
UIButton *button; // the button you want to show the popup sheet from

UIAlertController *alertController;
UIAlertAction *destroyAction;
UIAlertAction *otherAction;

alertController = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
destroyAction = [UIAlertAction actionWithTitle:@"Remove All Data"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
// do destructive stuff here
}];
otherAction = [UIAlertAction actionWithTitle:@"Blah"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// do something here
}];
// note: you can control the order buttons are shown, unlike UIActionSheet
[alertController addAction:destroyAction];
[alertController addAction:otherAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];

UIPopoverPresentationController *popPresenter = [alertController
popoverPresentationController];
popPresenter.sourceView = button;
popPresenter.sourceRect = button.bounds;
[self presentViewController:alertController animated:YES completion:nil];

Editing for Swift 4.2, though there are many blogs available for the same but it may save your time to go and search for them.

if let popoverController = yourAlert.popoverPresentationController {
popoverController.sourceView = self.view //to set the source of your alert
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) // you can set this as per your requirement.
popoverController.permittedArrowDirections = [] //to hide the arrow of any particular direction
}

Swift UIAlertController - ActionSheet iPad iOS8 Crashes

The error message is telling you that you need to give the alert controller's popoverPresentationController a location so that it can position itself properly. This is easy to do -- just check to see if there's a popover controller and add the sender as the source.

If your button is a UIBarButtonItem:

if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = sender
}
self.presentViewController(alertController, animated: true, completion: nil)

Otherwise:

if let popoverController = alertController.popoverPresentationController {
popoverController.sourceView = sender
popoverController.sourceRect = sender.bounds
}
self.presentViewController(alertController, animated: true, completion: nil)

Present a UIAlertController from within a Popover in iOS8

Found it !
If this AlertController is presented inside a popover, it must provide the location information, either a sourceView and sourceRect, or a barButtonItem.

Like

resetWarning.popoverPresentationController?.sourceView = selectedCell?.contentView
resetWarning.popoverPresentationController?.sourceRect = selectedCell!.contentView.frame

My code had to look like that:

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

var previouslySelectedCell: UITableViewCell?
if checkedIndexPath != nil {
previouslySelectedCell = tableView.cellForRowAtIndexPath(checkedIndexPath)
}
var selectedCell = tableView.cellForRowAtIndexPath(indexPath)

let selectedCurrency = PortfolioCurrencyStore.sharedStore.allCurrencies[indexPath.row]

if selectedCurrency.symbol != GlobalSettings.sharedStore.portfolioCurrency {

// Warning : changing the portfolio currency will reset the portfolio
var resetWarning = UIAlertController(title: NSLocalizedString("Currency Picker VC:AS title", comment: "Changing currency will reset portfolio"), message: nil, preferredStyle: .ActionSheet)

// destructive button
let resetAction = UIAlertAction(title: NSLocalizedString("Currency Picker VC:AS destructive", comment: "Destructive button title"), style: .Destructive, handler: { (action: UIAlertAction!) in

// Remove checkmark from the previously marked cell
previouslySelectedCell?.accessoryType = .None

// Add checkmark to the selected cell
selectedCell?.accessoryType = .Checkmark
self.checkedIndexPath = indexPath

// Animate deselection of cell
self.tableView.deselectRowAtIndexPath(indexPath, animated:true)

// Stock the portfolio currency as NSUserDefaults
GlobalSettings.sharedStore.portfolioCurrency = selectedCurrency.symbol // link between portfolioCurrency as a String and currency.symbol as the property of a Currency instance.

// Delete all items from the StockStore
StockStore.sharedStore.removeAllStocks()
println("StockStore : all entries were deleted")

// Delete all items from the CurrencyRateStore
CurrencyRateStore.sharedStore.deleteAllRates()
println("CurrencyStore : all entries were deleted")

// Delete all items from the SalesJournal
SalesJournal.sharedStore.removeAllEntries()
println("SalesJournal : all Sales journal entries were deleted")


// Reload tableView
self.tableView.reloadData()

// On Regular sizes, the currency picker is presented inside a popover : reloadData of the List View
NSNotificationCenter.defaultCenter().postNotificationName("CurrencyPickerVC_PortfolioCurrencyDidChangeNotification", object:nil, userInfo:nil)

// Animate deselection of cell
tableView.deselectRowAtIndexPath(indexPath, animated:true)

// Return to root VC
self.navigationController?.popToRootViewControllerAnimated(true)

})



// cancel button
let cancelAction = UIAlertAction(title: NSLocalizedString("Currency Picker VC:AS cancel", comment: "Cancel button title"), style: .Cancel, handler: { (alertAction: UIAlertAction!) -> Void in
// Animate deselection of cell
self.tableView.deselectRowAtIndexPath(indexPath, animated:true)
})

resetWarning.addAction(resetAction)
resetWarning.addAction(cancelAction)

// If this AlertController is presented inside a popover, it must provide the location information, either a sourceView and sourceRect or a barButtonItem.
resetWarning.popoverPresentationController?.sourceView = selectedCell?.contentView
resetWarning.popoverPresentationController?.sourceRect = selectedCell!.contentView.frame

presentViewController(resetWarning, animated: true, completion: nil)


} else {
// Animate deselection of cell
tableView.deselectRowAtIndexPath(indexPath, animated:true)
}
}

Now the image looks like this:
Sample Image

UIAlertController shown on iPhone, not on iPad

If you look at the documentation for the sourceView property (https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller/1622313-sourceview), you see that it is defined as "The view containing the anchor rectangle for the popover."

This means that your popover is appearing off screen, since the anchor rectangle is the view itself.

To fix this, try modify the sourceRect property as well. Here's an example:

alertController.popoverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds), 1, 1);

You will see that this causes the alert to appear in the middle of the view.

popover

Action Sheet is not working in ipad ios 13.6

I have tried your code on iPhone(Device:- iPhone 11 Pro 13.6) and iPad(iPad pro (12.9- 4th generation) both and it works. But If you said, I have changed some popover frame, Use the following code:-

   let alert = UIAlertController(title: "Select Image", message: nil, preferredStyle:
UIAlertController.Style.actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: UIAlertAction.Style.default,
handler: { (res) in
self.btnClickedCamera(tag:2)
}))
alert.addAction(UIAlertAction(title: "Gallery", style: UIAlertAction.Style.default,
handler: { (res) in
self.btnClickedGallery(tag:2)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (res) in

}))
if let popoverPresentationController = alert.popoverPresentationController {

popoverPresentationController.sourceRect = sender.frame
popoverPresentationController.sourceView = self.view

}
self.present(alert, animated: true, completion: nil)

}


Related Topics



Leave a reply



Submit