How to Present Popover Properly in iOS 8

How to present popover properly in iOS 8

Okay, A housemate took a look at it and figured it out:

 func addCategory() {

var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
var nav = UINavigationController(rootViewController: popoverContent)
nav.modalPresentationStyle = UIModalPresentationStyle.Popover
var popover = nav.popoverPresentationController
popoverContent.preferredContentSize = CGSizeMake(500,600)
popover.delegate = self
popover.sourceView = self.view
popover.sourceRect = CGRectMake(100,100,0,0)

self.presentViewController(nav, animated: true, completion: nil)

}

That's the way.

You don't talk to the popover itself anymore, you talk to the view controller inside of it to set the content size, by calling the property preferredContentSize

How to present a UIViewController as a popover in Swift programmatically on iPhone

You can't do this in iPhone with portrait mode with this code ... you can check popover section in apple doc here..

It suggests that:

In iOS 8 and later, you use a UIPopoverPresentationController to present a popover. UIPopoverPresentationController defines a delegate that lets you adjust the display style of your popover content to suit the current display environment. For example, in a horizontally regular environment, your content can display inside a popover; in a horizontally compact environment, your content can display in a full-screen modal view.

And as I said, if you can check in iPad, your content can display inside a popover.

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
}

Present as Popover segues and view size

Something to watch for with popovers is that on devices like the iPad, the size class for the popover is not the same as the controller which raises it.

You will probably find that the size class goes from regular width to compact width when you use a popover on an iPad. If you have layout coded to regular width for your popover content, then it will not work in the popover.

The size of the popover itself comes from the content size properties for the controller presented. You can set this size explicitly in the attribute inspector for the view controller or in code. See: How to present popover properly in iOS 8

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



Related Topics



Leave a reply



Submit