Loading

Popup menu

Sometimes you just need a simple popup menu with a few options on it:

Simple popup menu

Just a few options that fire off a few actions.

So far we have used the UIAlertController to display messages. For this purpose, we extend its capabilities to a popup menu. Bulk of the code is the same, but we have a change of style to turn it into our menu.

        let message = UIAlertController(title: nil, message: nil,
                        preferredStyle: .actionSheet)

        let alertUpdates = UIAlertAction(title: "Check For Updates",
            style: .default, handler: { _ -> Void in
            self.initiateCheckForDownload(fromView: view)
        })

        let alertLight = UIAlertAction(title: "Light Theme",
            style: .default, handler: { _ -> Void in
            ColourHelper.currentTheme  = .light
        })

        let alertDark = UIAlertAction(title: "Dark Theme",
            style: .default, handler: { _ -> Void in
            ColourHelper.currentTheme = .dark
        })

        let alertAbout = UIAlertAction(title: "About",
            style: .default, handler: { _ -> Void in
            AppHelper.showAboutPopup(forView: view)
        })

        let alertClose = UIAlertAction(title: "Close", style: .cancel, handler: nil)

        message.addAction(alertLight)
        message.addAction(alertDark)
        message.addAction(alertUpdates)
        message.addAction(alertAbout)
        message.addAction(alertClose)
        message.preferredAction = alertClose

        message.popoverPresentationController?.barButtonItem = button

        view.present(message, animated: true, completion: nil)

First point to note is the definition the UIAlertController. We create it without a title and without any message. These are of no relevance to what we are trying to achieve. The other important point is that we define the preferredStyle as 'actionSheet. This is what is going to give us the popup menu styling.

We then define the menu items much as we did with buttons for message boxes. Each item is defined as a UIAlertAction along with the closure necessary to handle it being tapped.

We then add the buttons to the controller. As a final step, we define which of the buttons is going to be the preferred button, which is the one that appears at the bottom of the menu, slightly separated from the other buttons.

Finally, we present the view and we get the popup menu with actions.

iPad gotcha

So, I skipped one small detail. This code works great on an iPhone and dies spectacularly on an iPad if we miss one line of code:

  message.popoverPresentationController?.barButtonItem = button

On a phone, the real=estate of the screen is limited and the menu will appear on screen in a fixed place. On an iPad the menu needs to be anchored to a button. If it isn't, the iPad doesn't know where to put it so it crashes.

So, for the iPad, we anchor to a button and the menu appears attached to that button:

iPad simple popup menu

It's also worth noting that the Close button has disappeared on the iPad. Tapping anywhere on the screen will close the menu, so it's not required.