Xcode & Swift - Detecting User Touch of Uiview Inside of Uiscrollview

Xcode & Swift - Detecting user touch of UIView inside of UIScrollView

By setting userInteractionEnabled to NO for your scroll view, the view controller will start receiving touch events since UIViewController is a subclass of UIResponder. You can override one or more of these methods in your view controller to respond to these touches:

  • touchesBegan: withEvent:
  • touchesMoved: withEvent:
  • touchesEnded: withEvent:
  • touchesCancelled: withEvent:

I created some example code to demonstrate how you could do this:

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

// This array keeps track of all obstacle views
var obstacleViews : [UIView] = []

override func viewDidLoad() {
super.viewDidLoad()

// Create an obstacle view and add it to the scroll view for testing purposes
let obstacleView = UIView(frame: CGRectMake(100,100,100,100))
obstacleView.backgroundColor = UIColor.redColor()
scrollView.addSubview(obstacleView)

// Add the obstacle view to the array
obstacleViews += obstacleView
}

override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
testTouches(touches)
}

override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
testTouches(touches)
}

func testTouches(touches: NSSet!) {
// Get the first touch and its location in this view controller's view coordinate system
let touch = touches.allObjects[0] as UITouch
let touchLocation = touch.locationInView(self.view)

for obstacleView in obstacleViews {
// Convert the location of the obstacle view to this view controller's view coordinate system
let obstacleViewFrame = self.view.convertRect(obstacleView.frame, fromView: obstacleView.superview)

// Check if the touch is inside the obstacle view
if CGRectContainsPoint(obstacleViewFrame, touchLocation) {
println("Game over!")
}
}
}

}

Detect touch on UIButton below UIScrollview

I am not a Swift coder, i could link you all the methods , but I guess you can handle it yourself, unless you can't let me know I will update the answer. However, the solution for you:

First you need to add a UITapGestureRecognizer with a single tap to your UIScrollView.

Detect the tap CGPoint (user touchpoint) inside your tapGesture method:
(Objective-c)

CGPoint touchPoint=[gesture locationInView:scrollView];

Then do a check if the touchPoint is inside the view below it with CGRectContainsPoint

bool CGRectContainsPoint(CGRect rect, CGPoint point);

If so, just fire the action, otherwise ignore it. :)

Touch events on subclass of UIView as a subview of UIScrollView

There are several approaches you could try:

  1. Try setting the below properties on the UIScrollView:

    scrollView.delaysContentTouches = NO;
    scrollView.canCancelContentTouches = NO;

    See similar SO questions/answers here, here.

  2. Implement hitTest:withEvent:. See here, here.

  3. Use a UIGestureRecognizer. See here, here.

I would personally recommend using a UIGestureRecognizer, but it depends on your specific situation (any of these options may work fine for you).

Detect Touch Event On UIScrollView's Content

Your UIImageViews probably have user interaction disabled (which is what they default to). Call the following line on each image view, and your taps should be recognized:

yourImageView.userInteractionEnabled = YES; 

Make sure to do this before adding the gesture recognizer.

I had this exact issue a few weeks ago and this is what fixed it for me.

UiScrollview scrollviewDidScroll detect user touch

The UIScrollView has a panGestureRecogniser property, which tracks the pan gestures in the scroll view. You can track the state of the pan gesture in the scrollViewDidScroll to know exactly what state the panning is in.

Swift 4.0

func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.isEqual(yourScrollView) {
switch scrollView.panGestureRecognizer.state {
case .began:
// User began dragging
print("began")
case .changed:
// User is currently dragging the scroll view
print("changed")
case .possible:
// The scroll view scrolling but the user is no longer touching the scrollview (table is decelerating)
print("possible")
default:
break
}
}
}

Objective-C

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

if ([scrollView isEqual:yourScrollView]) {

switch (scrollView.panGestureRecognizer.state) {

case UIGestureRecognizerStateBegan:

// User began dragging
break;

case UIGestureRecognizerStateChanged:

// User is currently dragging the scroll view
break;

case UIGestureRecognizerStatePossible:

// The scroll view scrolling but the user is no longer touching the scrollview (table is decelerating)
break;

default:
break;
}
}
}

UIView inside UIScrollView not getting touch events

You may have solved this now but I had a similar problem and solved it so hopefully my experience can help anyone else with a similar issue.

In my case I had exactly the same setup my CustomUIView was capturing the touch events. In order to have UIView receive any touch events I needed to make a call to

[super touchesEnded:touches withEvent:event];

from the CustomUIView. Hope this helps!

How to capture touch events from a UIScrollView when user is scrolling the screen vertically on iOS with Swift?

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).



Related Topics



Leave a reply



Submit