ipadswiftios8xcode6uipopover

iOS 8 : Disable UIBarButtonItem when shown inside a popover


Now that XCode 6 and iOS 8 enable size classes, there is only one storyboard for all devices. Fine. But in the same time, Apple recommends to avoid using bar button items to dismiss a popover. Now, how can I do to have a UIBarButtonItem when presenting on an iPhone, and not when presented inside a popover on an iPad ?

Precision : I know how to disable a UIBarButtonItem based on the fact that the device is an iPad. I'm looking for a way to specifically detect that a popover is displayed.

EDIT: this code works, but I'd like something less device-dependent:

if traitCollection.userInterfaceIdiom == .Pad {
        navigationItem.rightBarButtonItem = nil
    }

EDIT: I created a small Github project to make my question clear : Github - Test Popover

Thanks!


Solution

  • I finally found how to solve that issue :


    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
               }
    // ....
    }
    


    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
    }
    

    }



    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: