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.
there's no need for a hit test on the UIScrollView
side. since the delay is set by the UIScrollView
itself. subclassing and implementing a custom hitTest: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:
yourScrollView.delaysContentTouches = NO;
unfortunately this disables events along the UISliders
track, so for this part your UIScrollView
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 subclass UISlider
and add the following:
// get the location of the thumb
- (CGRect)thumbRect
{
CGRect trackRect = [self trackRectForBounds:self.bounds];
CGRect thumbRect = [self thumbRectForBounds:self.bounds
trackRect:trackRect
value:self.value];
return thumbRect;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGRect thumbFrame = [self thumbRect];
// check if the point is within the thumb
if (CGRectContainsPoint(thumbFrame, point))
{
// if so trigger the method of the super class
NSLog(@"inside thumb");
return [super hitTest:point withEvent:event];
}
else
{
// if not just pass the event on to your superview
NSLog(@"outside thumb");
return [[self superview] hitTest:point withEvent:event];
}
}