0

I'm new to the iOS development and Swift and I have the following problem:

I would like to capture touch events from the screen. I have no problems with doing this on regular views. Unfortunately, I encountered issues with the UIScrollView component. When user is tapping on the screen, long pressing on the screen or moving finger horizontally, then I'm able to capture touches, but when user is moving finger vertically and activating vertical scrolling at the same time, then I'm not able to capture touches.

I found a few threads on StackOverflow regarding similar issue, but solutions provided there did not resolve my problem.

Structure of my views is as follows:

+- View (top-level view)
   |
   |
   +--- UIScrollView
        |
        |
        +-- other views inside...

Here is my code:

class MyViewController : UIViewController {
  @IBOutlet weak var scrollView: UIScrollView!

  override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(myRecognizer)
  }
}

Gesture recognizer is added into the top-level view.

I also have basic custom implementation of the UIGestureRecognizer:

class MyRecognizer: UIGestureRecognizer {
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        // handle events...
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)
        // handle events...
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesEnded(touches, with: event)
        // handle events...
    }
}

What did I try to do to solve this issue?

  • setting parameter scrollView.canCancelContentTouches = false - didn't help
  • setting parameter scrollView.isScrollEnabled = false - I was able to capture all touch events, but scrollView stopped working - didn't help
  • adding gesture recognizer to the scrollView and removing it from the top-level view - didn't help
  • adding gesture recognizer both to the scrollView and the top-level view - didn't help
  • setting parameter scrollView.isUserInteractionEnabled = false - I was able to capture all touch events, but scrollView and all UI components stopped working - didn't help
  • reordering calls in MyRecognizer class: handling events first and then calling method from the upper class super.touches... - didn't help

Right now, I have no idea what else I can do to capture touch events inside the UIScrollView while user is scrolling the screen vertically.

Any suggestions or help are appreciated!

Regards,

Piotr

Piotr Wittchen
  • 3,853
  • 4
  • 26
  • 39

1 Answers1

1

So UIScrollView has its own set of gestures that have cancelsTouchesInView set to true by default. Try setting this property to false for each gesture in the scrollview like so:

for gesture in scrollView.gestureRecognizers ?? [] {
    gesture.cancelsTouchesInView = false
}

EDIT:

Solution to this problem is creating a separate custom UIScrollView and capture touches inside it. It is described in details in this thread: https://stackoverflow.com/a/70594220/10953499 (also linked in the comment).

Piotr Wittchen
  • 3,853
  • 4
  • 26
  • 39
yjoon
  • 106
  • 1
  • 5
  • Thank you for the suggestion, but unfortunately, It didn't help. – Piotr Wittchen Jan 28 '22 at 16:16
  • 1
    I see, that's unfortunate. I do have a more detailed answer for a similar question, though it involves creating a subclass of UIScrollView. If you'd like you can try refer to it [here](https://stackoverflow.com/a/70594220/10953499) – yjoon Jan 29 '22 at 13:24
  • Thanks for this link. I will check it out. I'd rather avoid creating a subclass of this view, but maybe that's the only solution in this case. – Piotr Wittchen Jan 30 '22 at 16:06
  • 1
    Finally, I used proposed path with the custom `UIScrollView`, you provided in another thread. I edited your reply and marked it as a solution to my problem. Thanks. – Piotr Wittchen Feb 07 '22 at 10:00