UIPopoverController, Xcode 6, IOS 8 using Swift
Here is a simple example for iOS 8. Popover are presented using adaptivity apis in iOS 8.
class PlayerInformationTableViewController: UITableViewController, UIPopoverPresentationControllerDelegate, NSFetchedResultsControllerDelegate{
...
@IBAction func addPopover(sender: UIBarButtonItem){
let playerInformationViewController = PlayerInformationViewController()
playerInformationViewController.modalPresentationStyle = .Popover
playerInformationViewController.preferredContentSize = CGSizeMake(300, 300)
let popoverPresentationViewController = playerInformationViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .Any
popoverPresentationViewController?.delegate = self
popoverPresentationController?.barButtonItem = sender
presentViewController(playerInformationViewController, animated: true, completion: nil)
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle{
return .None
}
}
How to make UIPopoverController (Swift)?
* Updated Answer *
class ViewController: UIViewController, UIPopoverControllerDelegate, UIPopoverPresentationControllerDelegate {
@IBOutlet weak var RoutineLabel: UIButton!
@IBAction func RoutineButton(sender: AnyObject) {
switch SDiPhoneVersion.deviceVersion() {
case DeviceVersion.iPad1, DeviceVersion.iPad2, DeviceVersion.iPadMini, DeviceVersion.iPad3, DeviceVersion.iPad4, DeviceVersion.iPadAir, DeviceVersion.iPadMiniRetina:
var popoverViewController = self.storyboard?.instantiateViewControllerWithIdentifier("RoutinesTableViewController") as UITableViewController
popoverViewController.modalPresentationStyle = .Popover
popoverViewController.preferredContentSize = CGSizeMake(300, 300)
let popoverPresentationViewController = popoverViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = UIPopoverArrowDirection.Up
popoverPresentationViewController?.delegate = self
popoverPresentationViewController?.sourceView = self.RoutineLabel
popoverPresentationViewController?.sourceRect = CGRectMake(RoutineLabel.frame.width / 2, RoutineLabel.frame.height,0,0)
presentViewController(popoverViewController, animated: true, completion: nil)
default:
println("iPhones")
}
}
}
Notes:
- my PopPoverViewController is a UITableViewController
- I use SDiPhoneVersion.deviceVersion to check for device version
- I use a button to trigger it
- I make the start of my pop up depend on RoutineLabel.frame
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
iOS 8 : Disable UIBarButtonItem when shown inside a popover
I finally found how to solve that issue :
- In the storyboard, I removed the "close" bar button item in the navigation bar of the view controller I want to display as a popover on iPad and a modal VC on iPhone. So now this controller is embedded in a navigation controller, but without a "close" button.
- In the caller view controller (the one which has a bar button item to call the popover), I added the following code in the prepareForSegue (my segue is a Popover segue by the way)
PrepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
// switch on the segue.identifier
// ....
case .DisplayPreferences:
print("Segue to Preferences")
if let popoverPresentationController = segue.destinationViewController.popoverPresentationController {
popoverPresentationController.delegate = self
}
// ....
}
- I added the following extension so that the caller view controler conforms to UIPopoverPresentationControllerDelegate protocol
UIPopoverPresentationControllerDelegate:
// MARK: - UIPopoverPresentationController Delegate methods
extension StockListTableViewController: UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .FullScreen
}
func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
if let navigationVC = controller.presentedViewController as? UINavigationController,
let preferencesVC = navigationVC.visibleViewController as? PreferencesTableViewController {
// This Bool indicates whether the popover controller should display the bar button item or not
preferencesVC.shouldShowCloseButton = true
}
return controller.presentedViewController
}
}
- Finally, in the called view controller (which is a popover on iPad but modal on iPhone), I added the following code:
property:
var shouldShowCloseButton = false
viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
// Close button
if shouldShowCloseButton {
let closeButton = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: #selector(PreferencesTableViewController.doneButtonTapped(_:)))
navigationItem.setRightBarButtonItem(closeButton, animated: true)
}
}
doneButtonTapped:
func doneButtonTapped(sender: UIBarButtonItem) {
navigationController?.dismissViewControllerAnimated(true, completion: nil)
}
For me, this worked perfectly:
on iPhone, I get a view controller presented modally, with a "close"
button item in a navigation controller, which allows me to dismiss iton iPad, I get a popover without a "close" button because with a popover th expected behavior is to tap outside the popover to
dismiss it.
UIPopoverController for iphone not working?
Edit: As stated by Soberman, since iOS 8 it is possible to present popovers on iPhone using public APIs, so this answer is probably not relevant anymore.
As stated in Apple's documentation on UIPopoverController:
Popover controllers are for use exclusively on iPad devices.
So there is no way to use this class in iPhone application unfortunately. But there are a couple of custom third-party implementations of the functionality provided by UIPopoverController which add iPhone support and more. See https://github.com/50pixels/FPPopover for example.
Edit: There also is another highly customizable popover implementation for both iPhone/iPad worth checking out: https://github.com/nicolaschengdev/WYPopoverController.
How to reach UIPopoverController from its content view controller?
Good Option : Use delegate
to dissmiss popover from contentView.
Another option : In iOS 8
, you can dismiss the popover by using dismissViewControllerAnimated:completion:
from within the popover. Note it doesn't work in iOS 7
.
UIPopoverController for iphone in ios8 shows white screen
Try to use the new iOS 8 API for popovers.
pickerController = [[UIViewController alloc] init];
UIView *viewV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 160)];
[viewV setBackgroundColor:[UIColor clearColor]];
UIPopoverPresentationController *popOverController = pickerController .popoverPresentationController;
popOverController.popoverContentSize = CGSizeMake(150, 160);
[popOverController setDelegate:self];
popOverController.sourceView = self.view;
popOverController.sourceRect = sender.frame;
popOverController.permittedArrowDirections = UIPopoverArrowDirectionUp;
[self presentViewController:popOverController
animated:YES
completion:nil];
Related Topics
How to Write an 'If Case' Statement as an Expression
Reducing the Number of Brackets in Swift
Button Border with Transparent Background in Swift
Xcode Error: Missing Required Module 'Firebase'
Xcode Autocomplete Does Not Work in Sources Folder of Swift Playgrounds
How to Make a Uiview Focusable Using the Focus Engine on Apple Tv
Swiftui - How to Set the Title of a Navigationview to Large Title (Or Small)
Swift Optional Escaping Closure
Apple MACh-O Linker Error, After Changing Project Name
Using Just with Flatmap Produce Failure Mismatch. Combine
How to Simulate Traits/Mixins in Swift
Nspredicate with Swift and Core Data
How to Prevent Actor Reentrancy Resulting in Duplicative Requests
Difference Between Switch Cases "@Unknown Default" and "Default" in Swift 5
How to Perform a Curl Request in Swift
How to Add Auto-Complete Comment in Xcode (Swift)
Using Cocoa Nssavepanel in Sandbox Causes Assertion Failure
Uicollectionviewcell Register Class Fails, But Register Nib Works