Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
417 views
in Technique[技术] by (71.8m points)

iphone - UISlider and UIScrollView

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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];
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...