I have a UISlider
as part of a view that is loaded into a UIScrollView
with paging enabled. I've noticed an unexpected behavior. If the user tries to use the slider quickly (i.e. press and move) it "activates" the scroll view, causing the page to switch. However, if your press and hold for a second the slider "activates" and you can then adjust the slider value. This behavior is undesirable.
What is the best way to make the UISlider
responsive when loaded into a UIScrollView
? I've thought about adding a "blocker" view that just eats up touch events that is placed under the slider, but not sure if this is the best way to go about it.
most upvoted comment code in Swift 3 :)
You can subclass UIScrollView and override the method
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
as follows:Also Set
yourScrollView.delaysContentTouches = NO;
property for the scrollview.there's no need for a hit test on the
UIScrollView
side. since the delay is set by theUIScrollView
itself. subclassing and implementing a customhitTest:withEvent:
won't help since it's still triggered with delay.i searched hours for an elegant solution to this, since i wanted to simulate apple's own volumeslider in the ios application switcher.
the trick:
unfortunately this disables events along the
UISliders
track, so for this part yourUIScrollView
won't trigger any touchevents because they are caught by the slider first.to pass touchevents other than those which are in the
UISliders
thumb rect you have to subclassUISlider
and add the following:Have your scroll view detect touches over the region occupied by your slider (override
hitTest:withEvent:
, you may need to subclassUIScrollView
). If a touch over said region is detected, tell your scroll view to immediately pass the touch to the slider.My problem was a superset of this issue - I've got UISliders inside UITableViewCells and the whole UITableView is a page inside a UIScrollView. The sliders were wreaking havoc on the interactions with the other two and the subclassing solutions did not work. Here's what I came up with that's working great: send notifications when the sliders move and have the UITableView and UIScrollView disableScrolling on during this time. Note in the picture below: my sliders are horizontal, my tableview is vertical, and my UIScrollView has horizontal pages.

The UITableViewCell picks up events for the programmatically-created slider:
For the purposes of this tutorial, we only care about touchDown and Up:
Now, we catch in these notifications in both the UITableView (note that the tableview is in a VC but I'm sure this would work if you subclassed):
and the UIScrollView (same as above, enclosed in a VC):
I'd love to hear a more elegant solution, but this one definitely gets the job done. When you use a slider, the table and scrollviews hold still and when you click outside the sliders, the tableview and scrollviews move as expected. Also - notice that I could use non-subclassed instances of all 3 components in this solution. Hope this helps someone!
While creating an audio player I had the exact problem with a
sliderView
and it is added to ascrollView
, and whenever I touched thesliderView
, thescrollView
used to get the touch and instead of thesliderView
, thescrollView
moved . To avoid this , I disabled the srcolling of thescrollView
when the user touched thesliderView
and otherwise the scrolling is enabled .