Introduce UIAlertController from within Popover in iOS8

I set the UITableViewController to display in a popover on the iPad: UITableViewController inside a popover

When I click on the line, I show a warning to warn the user about a potential destructive action. I used the new UIAlertController and this is what happens: UIAlertViewController appears ...

The companion gets very small (actually the size of the alertController view). If I click Cancel, I will see the result: ... making the popover shrink!

Here is my code:

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") // Reload tableView self.tableView.reloadData() }) // cancel button let cancelAction = UIAlertAction(title: NSLocalizedString("Currency Picker VC:AS cancel", comment: "Cancel button title"), style: .Cancel, handler:nil) resetWarning.addAction(resetAction) resetWarning.addAction(cancelAction) presentViewController(resetWarning, animated: true, completion: nil) } else { // Animate deselection of cell tableView.deselectRowAtIndexPath(indexPath, animated:true) } } 

Did I miss something?

thanks for the help

+6
source share
2 answers

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

how

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

My code should have looked like this:

  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: enter image description here

+9
source

I had the same problem and I was not able to figure out how to prevent popover from resizing. Using an alert instead of an action sheet will also cause the popover to resize. The workaround I found was to use the Action Sheet as it is, setting the modal presentation style to UIModalPresentationPopover . I know that you use Swift, but my code is Objective-C; hope you can easily translate:

 - (UIAlertController *)modalAlertWithTitle:(NSString *)title andMessage:(NSString *)message fromViewController:(UIViewController *)sender { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleActionSheet]; // This will turn the Action Sheet into a popover [alertController setModalPresentationStyle:UIModalPresentationPopover]; // Set Modal In Popover to YES to make sure your popover isn't dismissed by taps outside the popover controller [alertController setModalInPopover:YES]; // Get the PopoverPresentationController and set the source View and Rect so the Action Sheet knows where to pop up UIPopoverPresentationController *popPresenter = [alertController popoverPresentationController]; popPresenter.sourceView = sender.view; popPresenter.sourceRect = sender.view.bounds; return alertController; } 

It is very important that you remember to set the undo style for UIAlertAction by default. If you set the Cancel style, it will not appear in the action sheet, since it uses ModalPresentationPopover. Users will also not be able to cancel by clicking outside the action sheet, since we installed ModalInPopover in YES. Setting the default cancel button style ensures that it appears on the sheet.

I just did it as a utility method in my AppDelegate so that I could name it from all my popovers. This works, but it’s not really an ideal solution, because if something triggers a warning when one of your popovers gets up, it can be changed. Please let me know if you find out how to prevent resizing altogether. Good luck

+4
source

Source: https://habr.com/ru/post/975181/


All Articles