Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 361
Erken Avatar asked Feb 22 '15 14:02

Erken


1 Answers

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.

like image 111
GoZoner Avatar answered Nov 13 '22 05:11

GoZoner