iOS 8
popover presentation
iOS development
app design
user interface

How to present popover properly in iOS 8

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In iOS 8, popovers are presented through UIPopoverPresentationController rather than the old iPad-only popover APIs. To present one correctly, you must set the controller's modal style to popover, anchor it to a source view or bar button item, and handle adaptation if you want popover behavior on compact-size devices.

Set the Modal Presentation Style to Popover

The presented view controller must use UIModalPresentationPopover. Without that, iOS treats it like a normal modal presentation.

swift
1import UIKit
2
3final class HostViewController: UIViewController, UIPopoverPresentationControllerDelegate {
4    @IBAction func showPopover(_ sender: UIButton) {
5        let content = UIViewController()
6        content.view.backgroundColor = .systemBackground
7        content.preferredContentSize = CGSize(width: 260, height: 180)
8        content.modalPresentationStyle = .popover
9
10        if let popover = content.popoverPresentationController {
11            popover.sourceView = sender
12            popover.sourceRect = sender.bounds
13            popover.permittedArrowDirections = [.up, .down]
14            popover.delegate = self
15        }
16
17        present(content, animated: true)
18    }
19}

That preferredContentSize call is important because the popover needs a reasonable size before presentation.

Always Provide an Anchor

On iPad, a popover needs a clear anchor. That means either:

  • 'sourceView plus sourceRect, or'
  • 'barButtonItem'

If you forget to provide one, the app can crash at presentation time because iOS does not know where the popover arrow should point.

For a navigation bar item, use this version:

swift
1@IBAction func showFromBarButton(_ sender: UIBarButtonItem) {
2    let content = UIViewController()
3    content.view.backgroundColor = .systemBackground
4    content.preferredContentSize = CGSize(width: 240, height: 160)
5    content.modalPresentationStyle = .popover
6
7    if let popover = content.popoverPresentationController {
8        popover.barButtonItem = sender
9        popover.permittedArrowDirections = .any
10        popover.delegate = self
11    }
12
13    present(content, animated: true)
14}

Use the bar-button anchor when the trigger lives in the navigation or toolbar rather than in the view hierarchy.

Keep Popover Behavior on Compact Width When Needed

On compact devices, iOS 8 may adapt a popover into a full-screen or over-current-context presentation unless you override the adaptive style. If you want the presentation to remain a popover, return .none from the delegate.

swift
1func adaptivePresentationStyle(
2    for controller: UIPresentationController
3) -> UIModalPresentationStyle {
4    return .none
5}

This delegate method is the difference between "works as a popover on iPad" and "still behaves like a popover when adaptation would otherwise change it."

Put Real Content in a Dedicated Controller

For production code, the popover should usually present a dedicated view controller rather than a blank generic one. That controller can own its controls, validation, and dismissal logic.

swift
1final class ColorChooserViewController: UIViewController {
2    override func viewDidLoad() {
3        super.viewDidLoad()
4        view.backgroundColor = .systemBackground
5        preferredContentSize = CGSize(width: 280, height: 220)
6    }
7}

Then present it exactly the same way:

swift
let chooser = ColorChooserViewController()
chooser.modalPresentationStyle = .popover

This keeps the popover content maintainable and avoids mixing layout logic into the presenting controller.

Dismissal and User Experience

Popovers are meant for lightweight, contextual interactions. They dismiss easily when the user taps outside, so they work well for pickers, short forms, and menus. They are a poor fit for long workflows or anything that requires multiple heavy navigation steps.

Keep the content focused:

  • short action lists
  • lightweight settings
  • compact forms
  • preview content

If the content starts feeling like a full screen, it probably should be a full screen.

Common Pitfalls

The biggest mistake is forgetting to set modalPresentationStyle = .popover, which means there is no popover controller to configure. Another frequent issue is omitting the source anchor, especially when presenting from a button inside a view. Developers also get confused when the popover turns into a full-screen modal on compact width because they did not implement the adaptive presentation delegate. Finally, popovers that are too large or too complex usually create a worse user experience than a standard modal screen.

Summary

  • Set the presented controller's modal style to .popover.
  • Provide either sourceView plus sourceRect or barButtonItem so iOS can anchor the popover.
  • Set preferredContentSize so the popover has a usable size.
  • Return .none from the adaptive presentation delegate if you want to preserve popover behavior.
  • Use popovers for lightweight contextual UI, not for long or complex workflows.

Course illustration
Course illustration

All Rights Reserved.