KevinB
KevinB

Reputation: 2484

Swift - Hide view if touch outside of it

I'm currently coding a calendar system on my app. I already show / hide the calendar with a UIButton, with toogleCalendar() function that I created.

I would like to hide the Calendar when the calendar is displayed and if the user touch outside of it.

Something like that:

enter image description here

If I click outside of the calendar, the calendar disappear.

I tried to insert a subview and add a GestureRecognizer on it but it's not working.

Do you have any idea about how I could do that?

This is the toggle function:

func toggleCalendar(){
      if !calendarIsHidden {
         calendarIsHidden = true

         UIView.animate(withDuration: 0.2, animations: {
            self.shadowCalendarView.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
            self.shadowCalendarView.alpha = 0
         }) { (finish) in
            if finish {
               self.shadowCalendarView.isHidden = self.calendarIsHidden
            }
         }

      } else {

         calendarIsHidden = false
         self.shadowCalendarView.isHidden = self.calendarIsHidden

         UIView.animate(withDuration: 0.2, animations: {
            self.shadowCalendarView.transform = .identity


            self.shadowCalendarView.alpha = 1

         }) { (finish) in
            // Nothing for now
         }

      }

}

Upvotes: 1

Views: 5444

Answers (3)

Solayman Rana
Solayman Rana

Reputation: 331

In Swift 5.1

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
    {
        let touch = touches.first
        if touch?.view != self.yourView { 

          // Do whatever you wanna do
          yourView.isHidden = true
        }
    }

Upvotes: 0

Ctibor Šeb&#225;k
Ctibor Šeb&#225;k

Reputation: 133

You see how the screen blurs to darker color when the child view is open? You can add a black view with 0.5 (for example) alpha below your calendar and add a UIGestureTapRecognizer to it like so (I assume that is what shadowCalendarView is for?) :

// Somewhere in the code, for example on viewDidLoad if its a UIViewController, or anywhere in your dismissal function:
shadowCalendarView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(yourClassName.handleDismiss)))

@objc func handleDismiss() {
    // Dismisses the calendar with fade animation
    UIView.animate(withDuration: 0.3, animations: {
        self.calendarView.alpha = 0.0
        self.shadowCalendarView.alpha = 0.0
    }) { ( finished ) in
        self.calendarView.isHidden = true
        self.shadowCalendarView.isHidden = true
        // If you are implementing calendar as a child view, remove it in the completion block of the animation like so:
        self.willMove(toParentViewController: nil)
        self.view.removeFromSuperview()
        self.removeFromParentViewController()
    }
}

If this answer is not clear enough, try to provide more information and I will try to edit accordingly. For example the implementation, is it a new ViewController as a childView? Is it a View only?

Upvotes: 2

Shubham Bakshi
Shubham Bakshi

Reputation: 572

Add a UITapGestureRecognizer to your self.view and inside the action part of the constructor of UITapGestureRecognizer you will input a function in which you will present the logic for checking if your calendar is presented/enabled and can further hide it .

let mytapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
self.view.addGestureRecognizer(mytapGestureRecognizer)
self.isUserInteractionEnabled = true

func handleTap(_ sender:UITapGestureRecognizer){

  if !calendarIsHidden {
   calendarIsHidden = true

   //Hide the calendar here

  }
  else {
   calendarIsHidden = false

   // Show the Calendar Here
  }

}

Upvotes: 3

Related Questions