4

I want to remove UIView from screen after user tap something except that view. (to visualize it for you I will upload sketch of my view)

enter image description here

And I want to remove blue UIView after user tap on something except buttons in this view. What should I use?

EDIT: In blue UIView are two buttons and I want to remove that view when user tap on background image

I did what @yerpy told me to do but it isn't working.

func test(gestureRecognizer: UITapGestureRecognizer) {
    print("test")
}

func setUpBackgroundImageView() {
    self.view.addSubview(backgroundImageView)
    backgroundImageView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    backgroundImageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
    backgroundImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    backgroundImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    let tap = UITapGestureRecognizer(target: self, action: #selector(test(gestureRecognizer:)))
    backgroundImageView.addGestureRecognizer(tap)
    tap.delegate = self
}

And I also add shouldReceiveTouch function to UIGestureRecognizerDelegate. What am I doing wrong?

3
  • Make the background a UIControl and add action to it... Commented Aug 19, 2017 at 16:33
  • But UIControl is slider yes? Commented Aug 19, 2017 at 16:39
  • Nope, UIControl is just a view to which you can connect actions in the same way as to a button (button is actually a type of UIControl). It's enough to just change the class of your view to UIControl. Commented Aug 19, 2017 at 16:54

5 Answers 5

9

Add UIGestureRecognizer to the super view :

As you said you have image view as a background.

 let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped(gestureRecognizer:)))
        imageView.addGestureRecognizer(tapRecognizer)
        tapRecognizer.delegate = self

Adding target action :

func tapped(gestureRecognizer: UITapGestureRecognizer) {
       // Remove the blue view.
    }

And then inside UITapGestureRecognizerDelegate :

extension ViewController : UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if touch.view!.superview!.superclass! .isSubclass(of: UIButton.self) {
            return false
        }
        return true
    }
}

Hope it helps !

EDIT

Make sure that user can touch on the view by enabling : self.view.userInteractionEnabled = true

Sign up to request clarification or add additional context in comments.

15 Comments

i have edited my question, it will work if I add UIGestureRecognizer to my background image?
But I don't have to do this function in UITapGestureRecognizerDelegate yes?
You have to implement this delegate function which will ignore sublacces of type (...)
I did what u told me to did but It isn't working, can u look on my code in answer below and help me?
What debug says in delegate method at if statement? The tap is recived, or its not ?
|
1

1- Add a view below your view, let call it overlay (gray one)

2- Add your container view with all your buttons inside (green one)

3- Add a tap gesture to the overlay (drag tap to overlay view)

4- Create a @IBAction of the tap to the viewcontroller

5- Write code to hide your green view inside the @IBAction

Image

Image

7 Comments

Combining tap recognizers and buttons is not wise. The recognizer will trigger even if the buttons are pressed, unless you manually exclude them in the delegate, which is not trivial.
Button touch cancel the tap event and doesn't pass it to super views. So the overlay wont trigger if you press a button. Will only read tap on overlay not on any other view.
That's not given. It more or less depends on the settings of the recognizer.
Not true, yes its given by default.
Actually, what usually happens is that the tap recognizer handles the event first and cancels the event on the button...
|
0

you can use UITapGestureRecognizer for that view

   override func viewDidLoad() {
        super.viewDidLoad()

        // Add "tap" press gesture recognizer
        let tap = UITapGestureRecognizer(target: self, action: #selector(tapHandler))
        tap.numberOfTapsRequired = 1
        backgroundimage.addGestureRecognizer(tap)
    }

    // called by gesture recognizer
    func tapHandler(gesture: UITapGestureRecognizer) {

        // handle touch down and touch up events separately
        if gesture.state == .began {

        } else if  gesture.state == .ended {

        }
    }

Comments

0

You can

  1. subclass with that background view, and implement an inherited method -beganTouches:(there is another para but I forget what it is)
  2. Add a UITapGestureRecognizer to that view

Comments

0

Add a giant button that covers the entire screen under all the buttons. Anytime the user presses on the giant button underneath the smaller buttons, do what you want it to do.

Not the most elegant but it works :P

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.