How to enable a popup sub menu when click + on the right?

How to enable a popup sub menu when click + on the right?

I want to have more than one choice, one for new reocord, one for import from a web link.

Replies

What is your set up ?


You have a NSPopUpButton ; was it defined in IB ? Is it a pop up or a pull down ?


What is the + on the right ? Usually, on OSX, you have 2 arrows on the right.


Do you want to enable sub menu in the pop up ? When was it disabled ?

in my iOS app, so far, when I click +, it will go to new record view.

but I have more than one choice when click +, so I want a popup menu show up, is there any floating menu like that is iOS?

On which object do you click + ?


Can't you override the func called by the tap on + ?

There's no simple "popup sub menu" which you can use with just enabling it.

You should better learn what sort of UI elements iOS provides.

Apple's Human Interface Guidelines would be a good place to see.

Views

Controls

You can use Action Sheets or Popovers or maybe some others. It's you to design your app. Which do you want to use?

override is only one choice? I want to provide the user two choices.

I am using the "RightBar Button Items" Add/+. I can add one more Bar Button Item side by side.

but a popup menu give fexibility when adding more in the future.

And there's no "popup menu" in iOS, which do you choose?

Popovers

Is the '+' button the button of the Master Detail ?


If so, I have created a Master Detail project.


In MasterViewController, I completed the insertNewObject handler to propose 2 options in an alert.


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        navigationItem.leftBarButtonItem = editButtonItem

        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
        navigationItem.rightBarButtonItem = addButton
        if let split = splitViewController {
            let controllers = split.viewControllers
            detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
        super.viewWillAppear(animated)
    }

    @objc
    func insertNewObject(_ sender: Any) {
        let alertController = UIAlertController(
            title:"Select option!", message: "You need to create the active report or select an existing report first.",
            preferredStyle: UIAlertController.Style.alert)
        let option1Action = UIAlertAction(title: "Option1", style: .default, handler: { (action) -> Void in
            print("choice1")
        })
        let okAction = UIAlertAction(title: "Ok", style: .default, handler: { (action) -> Void in
            self.objects.insert(NSDate(), at: 0)
            let indexPath = IndexPath(row: 0, section: 0)
            DispatchQueue.main.async {
           self.tableView.insertRows(at: [indexPath], with: .automatic)
            }

        })
        alertController.addAction(option1Action)
       alertController.addAction(okAction)
        present(alertController, animated: true, completion: nil)
    }

Ok, a simple example of using Popover.


You need your "popup menu" as a ViewController in Main.storyboard with Storyboard ID "PopupMenuVC".


import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(self.addBarButtonPressed))
    }
    
    @objc func addBarButtonPressed(_ sender: UIBarButtonItem) {
        guard let popup = self.storyboard?.instantiateViewController(withIdentifier: "PopupMenuVC") else {
            print("PopupMenuVC cannot be instatiated")
            return
        }
        popup.modalPresentationStyle = .popover //<-
        
        guard let presentation = popup.popoverPresentationController else {
            print("popoverPresentationController is nil")
            return
        }
        presentation.barButtonItem = sender //<-
        //presentation.preferredContentSize = ...
        presentation.delegate = self //<-
        self.present(popup, animated: true, completion: nil)
    }
    
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
    }
}

OK, so the viewController (VC1) launched the popover PopupMenuVC, each menu item on PopupMenuVC

will go to a separate VC2 or VC3, will OK on VC2/VC3 go back to VC1?


VC1 -> PopupMenuVC -> VC2/VC3.

Yes, it is on the Master/Detail, master view controller to add a new item.

Was your option to create alert items on the bottom?

Option was to use an alert to let user select between several options when clicking on +


I tested, it does work.


Is it the UI you want ? That's your decision ; advantage of alert is that it leaves time to user and you have room to add some explanation. Now if you have 10 choices, that may not be the best way.

VC1 -> PopupMenuVC -> VC2/VC3


That may be possible, but it's better to use .popover style modal as modal.


VC1 ⇄ PopupMenuVC

VC2/VC3


You may need to tell something to VC1, when PopupMenuVC is dismissed.

The doc says "Avoid displaying popovers on iPhones." What about UITextView?