-1

I dragged a ViewController onto my storyboard, segued to it with a popover segue, and setup the size and style in the presentingVC's prepareForSegue. My question is, if my popover has several buttons, where should their code be executed?

  1. For example, should I use a delegation pattern where, in the prepareForSegue, I pass the delegation reference as self? Then delegate backward?
  2. Or, should I create a new viewController for the popover, then put the code to be run in there?
  3. I also read this tutorial and someone said...

" And you get hold of the the content controller by using the popoverPresentationController.presentedViewController method in the UIPopoverPresentationController

What would be ideal for me, since the code I want will change some presentingVC variables, would be delegate back to the presenting VC.

Community
  • 1
  • 1
Dave G
  • 12,042
  • 7
  • 57
  • 83

2 Answers2

0

Just set the popover button actions in prepareForSegue to point to functions in the presentingVC.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let dest = segue.destinationViewController as? MyPopoverViewController {
        let myButton = dest.view.viewWithTag(MY_BUTTON_TAG) as! UIButton
        myButton.addTarget(self, action: "onMyButton", forControlEvents: .TouchUpInside)
    }
}

func onMyButton() {
    ...
}

Or even better with closures using an UIButton extension like this:

https://www.mikeash.com/pyblog/friday-qa-2015-12-25-swifty-targetaction.html

Tapani
  • 3,191
  • 1
  • 25
  • 41
  • 1
    Thanks Tapani. I've never seen any method like this before. Would you mind explaining why this is the way to do it? I like to progress as a developer and not just implement code in my app without understanding it. Why this new way and not delegation? – Dave G Feb 07 '16 at 13:52
  • 1
    I don't believe this will work. The outlets in the `destinationViewController` are not setup at `prepareForSegue` time, so `dest.myButton` would be `nil`. – vacawama Feb 07 '16 at 14:24
  • You can always find the button by tag. That way the outlets don't need to be set and you don't even need a class for the popover view controller. – Tapani Feb 07 '16 at 14:44
  • I think delegates became outdated when block were introduced to Objective-C and even more with Swift closures. I would create a class for the popoverOverViewController, connect IBActions and call a closure in the action handler. In prepareForSegue I would set the closure, which the action handler calls. viewWithTag approach, however, requires less code. – Tapani Feb 07 '16 at 14:49
0

Ultimately just went with delegation in the competition block of the dismiss popover call:

class NavigationViewController: UIViewController {

    var presentingVC_Delegate: mainLists_PopoverDelegation!
    var whatToDo = "Placeholder"

    @IBOutlet var shareBtn: UIButton!
    @IBOutlet var clearBtn: UIButton!
    @IBOutlet var settingsBtn: UIButton!

    //***** ----- ***** ------ ***** ----- ***** ----- *****
    //Menu Button Functions
    //***** ----- ***** ------ ***** ----- ***** ----- *****
    @IBAction func shareBtn_Pressed(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: { finished in
            self.presentingVC_Delegate.call_ActivityVC()
        })
    }
    @IBAction func clearBtn_Pressed(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: { finished in
            self.presentingVC_Delegate.deleteList()
        })
    }
    @IBAction func settingsBtn_Pressed(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: { finished in
            self.presentingVC_Delegate.presentSettingsVC()
        })
    }
}

protocol mainLists_PopoverDelegation {
  func call_ActivityVC ()
  func deleteList ()
  func presentSettingsVC ()
}

With those three functions located in the main VC.

Dave G
  • 12,042
  • 7
  • 57
  • 83