UIButton that will ignore drag and drop and pass it to UIScrollView

I know that there are similar posts in Stack, but nothing I found helped me find a solution.

  • I have scrollview added in a UIView .
  • I added a UIButton to the same UIView over scrollview .

    • I want UIButton to respond to touchUp and fire an event.
    • If someone is DRAGS in UIButton, I want him to pass the event to scrollView and drag the UIScrollView without triggering the button event.

I know how to pass touch with hitTest by returning scrollview, but this stops everything that gets into UIButton.

I do not want to add UIButton to UIScrollView.

Does anyone have a suggested solution?

+6
source share
4 answers

As explained in this answer , UIButton or another UIControl, which is a scrolling type view, automatically responds to taps, allowing you to drag the scroll view knob. However, buttons, which are scrolling-type routines, also move with scrolled content, rather than staying at the same position on the screen when the content scrolls under them. I assume that is why you do not want to embed buttons in the scroll bar.

If this happens, you can get the desired behavior with one more step. Put all your buttons in a UIView, which is a preview in the scroll view, and then in the scrollViewDidScroll method of the scroll view delegate, set this frame.origin parameter to the scroll content view of Offset. I just implemented this in my application and it works great, without having to do any subclasses or participate in the responder chain or touch events.

0
source

Try the following:

  • Add a transparent, custom UIView, as big as the whole scroll, show contentSize as a scroll across all other views. (Or, conversely, make it the size of the scroll width / height and simply move it each time the scroll view moves.) When the scroll view decides to pass its touches to its subzones instead of dragging, this will be the first thing hitTested needs to do.
  • Override the hitTest method for UIView. Check if the touch is inside the button frame. If so, return the button; if not, return zero.

In essence, you will fool the scroll view, thinking that the button is one of its subzones. I'm not sure if this will work, as I have not really tried, but it seems quite reasonable.

+1
source

Try adding a UIPanGestureRecognizer to a UIBUtton . In the callback you specify to handle panning (dragging and dropping), you don't need to implement anything. Then set cancelsTouchesInView to YES. This will cause your button to move the drag and drop gestures to other views.

  UIPanGestureRecognizer * gr = [[UIPanGestureRecognizer alloc] initWithTarget: self action: @selector (handlePan)];
         [gr setCancelsTouchesInView: YES];
         [myButton addGestureRecognizer: gr];
         [gr release];

And here is handlePan :

  - (void) handlePan
 {
     // Do nothing
 }

I faced a similar situation when I had a UIScrollView with two UIView subviews. Each UIView contained a UISlider . I wanted to catch (and fall) vertical drags (in which the gesture recognizer appeared), but I also need horizontal scrolls to work in the slider, as expected, and pan the scroll view left and right. It was a decision. (A gesture recognition device was attached to each UIView .)

+1
source

Try this: Subclass UIScrollView, return YES to the touchsShouldCancelInContentView: method.

+1
source

Source: https://habr.com/ru/post/888025/


All Articles