YellowPillow YellowPillow - 2 months ago 7
iOS Question

Using callbacks to reproduce UIAlertViewController

I want to reproduce the functionality of the UIAlertController as the class isn't very customisable. So here is what I did:


  1. Create a DeleteDeckViewController that only has two buttons Yes, and No, with a callback method

    class DeleteDeckViewController: UIViewController {

    var deleteDeck : ((deleteDeck : Bool) -> ())?

    @IBAction func yesButton(sender: AnyObject) {
    deleteDeck!(deleteDeck: true)
    }

    @IBAction func noButton(sender: AnyObject) {
    deleteDeck!(deleteDeck: false)
    }
    }

  2. In the main view controller when the delete button is pressed it creates a popup DeleteDeck

    func handleDelete(detailDeckView: DetailDeckView) {

    let deleteDeckViewController = DeleteDeckViewController(nibName: "DeleteDeckViewController", bundle: nil)
    let popup = PopupDialog(viewController: deleteDeckViewController, transitionStyle: .BounceDown, buttonAlignment: .Horizontal, gestureDismissal: true)
    presentViewController(popup, animated: true, completion: nil)

    deleteDeckViewController.deleteDeck(true) { () -> Void in
    print("Deck deleted")
    }
    }



What I want to do is to use a callback to tell my main view controller whether the user pressed yes or no and then do some actions depending on yes or no. Although, I don't know the correct way to do it. I've read a few articles on callbacks, but I don't know how to apply it in this situation. I've tried using delegates it's just that I would need to pass the DetailDeckView object around without it being used so that's why I thought callback would be a better choice.

Would someone be able to point me in the right direction?

Answer

Within DeleteDeckViewController you have declared the deleteDeck variable as a function. Therefore, when you use an instance of this class, you need to set it as a variable. Therefore you code would look more like that below (untested):

func handleDelete(detailDeckView: DetailDeckView) {

    let deleteDeckViewController = DeleteDeckViewController(nibName: "DeleteDeckViewController", bundle: nil)
    deleteDeckViewController.deleteDeck = myDeleteHandler
    let popup = PopupDialog(viewController: deleteDeckViewController, transitionStyle: .BounceDown, buttonAlignment: .Horizontal, gestureDismissal: true)
    presentViewController(popup, animated: true, completion: nil)
}

func myDeleteHandler(shouldDelete: Bool) {
    if shouldDelete {
        print("Delete deck")
    }
}

Also, in your code, rather than using deleteDeck! which will fail if deleteDeck is nil, it is better practice to use code like:

if let deleteDeck = self.deleteDeck {
    deleteDeck(true)
}

This will create a local non-Optional variable called deleteDeck, that can be assured to not contain nil.

Comments