1
votes

Scheme of views

Greetings to everyone!

I have :

  • A view - is main view of UIViewController
  • B view - is UIView and subview of A view (A_view.addsubview(B_view))
  • C view - is UICollectionView and subview of A view ...

What is problem?

I can`t catch touch, swipe events in parent view controller.

What do I mean?

When I try to catch touch event using :

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {...

in A View controller I can see such results.

I try to catch swipes by UIScreenEdgePanGestureRecognizer added to A_view

Touch on A View -> touchesBegan(...) -> works

Swipe on A View -> UIScreenEdgePanGestureRecognizer -> works

Touch on B View -> touchesBegan(...) -> works

Swipe on B View -> UIScreenEdgePanGestureRecognizer -> works

Touch on C View -> touchesBegan(...) -> doesn't work

Swipe on C View -> UIScreenEdgePanGestureRecognizer -> doesn't work

I noticed that I can catch touch events in C view controller.

Question

Is there possibility to catch swipe/touch events produced on C view ( UICollectionView) in A view controller (UIViewController).

My Goal

My goal is to make SideBar view, and when I try to catch swipe on the edge of screen over C view (UICollectionView) it just scrolling inside, but I want to open SideBar when finger start

3

3 Answers

1
votes

If you need the edge swipe gesture to be recognized over every scrollView. (UICollectionView is a UIScrollView)

extension UIScrollView {
    open override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        print("gesture recognizer should begin")
        print(gestureRecognizer)
        let app = UIApplication.shared.delegate as? AppDelegate
        if let view = app?.window?.rootViewController?.view, !(gestureRecognizer is UIScreenEdgePanGestureRecognizer) {
            let location = gestureRecognizer.location(in: view)
            if location.x < view.frame.maxX * 0.05 || location.x > view.frame.maxX * 0.95 {
                return false
            }
        }
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }
}
0
votes

Override the function: optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool in the parent A View & return appropriate BOOLs.
Keep in mind that for a view whose userInteractionEnabled attribute is set to true, any touches/gestures in that view won't be propagated to the parent view (unless shouldReceive touch is overrided to say otherwise)

0
votes
  1. I have added UIGestureRecognizerDelegate to parent classes of A View viewController.

    class A_viewController: UIViewController,UIGestureRecognizerDelegate{...
    
  2. I have added UIScreenEdgePanGestureRecognizer to A view - parent view.

    let rec = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handlePanGestRecognizer))
    rec.edges = .left
    rec.delegate = self
    A_view.addGestureRecognizer(rec)
    
  3. Using method gestureRecognizerShouldBegin(...) catch edge swipes, and calling handlePanGestRecognizer(...) method to produce action. If gestureRecognizer is UIScreenEdgePanGestureRecognizer than do action.

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool
    {
         if gestureRecognizer is UIScreenEdgePanGestureRecognizer
         {
             handlePanGestRecognizer(recognizer: gestureRecognizer as! UIScreenEdgePanGestureRecognizer)
         }
         return false
    }
    
  4. Beside that recognizer.state.rawvalue = 0, so recognizer.state is not .begun when handlePanGestRecognizer() method fired.

    func handlePanGestRecognizer(recognizer : UIScreenEdgePanGestureRecognizer){...