Is it possible to call a block completion handler from another function in iOS?

block, ios, objective-c-blocks, swift

Solution

Since you are implementing the `UICustomView`, all you need to do is store the 'completion handler' as part of the `UICustomView` class. Then you call the handler when `hide()` is invoked.

class UICustomView : UIView {
   var onHide: ((Bool) -> ())?

   func show (onHide: (Bool) -> ()) {
     self.onHide = onHide
     let rootViewController: UIViewController = ...
     rootViewController.view.addSubview(self)
   }

   func hide (sender:UITapGestureRecognizer){
    if let customView = sender.view as? UICustomView{
        customView.removeFromSuperview()
        customView.onHide?(true)
    }
}

Of course, every `UIView` has a lifecycle: `viewDidAppear`, `viewDidDisappear`, etc. As your `UICustomView` is a subclass of `UIView` you could override one of the lifecycle methods:

class UICustomView : UIView {
  // ...

  override func viewDidDisappear(_ animated: Bool) {
     super.viewDidDisappear (animated)
     onHide?(true)
  }
}

You might consider this second approach if the view might disappear w/o a call to `hide()` but you still want `onHide` to run.

Problem

I have a custom UIView with a UITapGestureRecognizer attached to it. The gesture recognizer calls a method called hide() to remove the view from the superview as such: ``` func hide(sender:UITapGestureRecognizer){ if let customView = sender.view as? UICustomView{ customView.removeFromSuperview() } } ``` The UICustomView also has a show() method that adds it as a subview, as such: ``` func show(){ // Get the top view controller let rootViewController: UIViewController = UIApplication.sharedApplication().windows[0].rootViewController!! // Add self to it as a subview rootViewController.view.addSubview(self) } ``` Which means that I can create a UICustomView and display it as such: ``` let testView = UICustomView(frame:frame) testView.show() // The view appears on the screen as it should and disappears when tapped ``` Now, I want to turn my show() method into a method with a completion block that is called when the hide() function is triggered. Something like: ``` testView.show(){ success in println(success) // The view has been hidden } ``` But to do so I would have to call the completion handler of the show() method from my hide() method. Is this possible or am I overlooking something?

Original source