iPhone:Programming UISlider to position at clicked location

旧街凉风 提交于 2019-11-28 08:45:26

Here is the part "left as a user exercise":

- (void) tapped: (UITapGestureRecognizer*) g {
    UISlider* s = (UISlider*)g.view;
    if (s.highlighted)
        return; // tap on thumb, let slider deal with it
    CGPoint pt = [g locationInView: s];
    CGFloat percentage = pt.x / s.bounds.size.width;
    CGFloat delta = percentage * (s.maximumValue - s.minimumValue);
    CGFloat value = s.minimumValue + delta;
    [s setValue:value animated:YES];
}

The way I did it is to subclass the slider and check in touchesBegan. If the user taps on the thumb button area (which we track) then ignore the tap, but any where else on the trackbar we do: :

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self];

    // if we didn't tap on the thumb button then we set the value based on tap location
    if (!CGRectContainsPoint(lastKnownThumbRect, touchLocation)) {

        self.value = self.minimumValue + (self.maximumValue - self.minimumValue) * (touchLocation.x / self.frame.size.width);
    }

    [super touchesBegan:touches withEvent:event];
}

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {

    CGRect thumbRect = [super thumbRectForBounds:bounds trackRect:rect value:value];
    lastKnownThumbRect = thumbRect;
    return thumbRect;
}

You can simply add a UITapGestureRecognizer to the slider, then pull out the UIEvent and Touches associated with it to figure out where along the UISlider the tap took place. Then set your slider's value to this calculated value.

UPDATE:

First, setup your slider and add the gesture recognizer to it.

UISlider *slider = [[[UISlider alloc] init] autorelease];
…
<slider setup>
…
UITapGestureRecognizer *gr = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderTapped:)] autorelease];
[slider addGestureRecognizer:gr];

Then implement the selector

- (void)sliderTapped:(UIGestureRecognizer *)gestureRecognizer {
    <left as a user excercise*>
}

*Hint: Read the docs to figure out how to get the locationInView extrapolated and figure out what the slider should be

It seems like just subclassing UISlider and returning always true to the beginTracking produce the desired effect.

iOS 10 and Swift 3

class CustomSlider: UISlider {
    override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        return true
    }
}

I was using the subclassed UISlider code to listen to ValueChanged events in ios6> in order to implement a snap-to-grid type of function.

This was broken when upgrading to iOS7 as it no longer fired the UIControlEventsValueChanged. For anyone having the same problem it is fixed by adding a line in the if() as below:

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self];

    // if we didn't tap on the thumb button then we set the value based on tap location
    if (!CGRectContainsPoint(lastKnownThumbRect, touchLocation)) {

        self.value = self.minimumValue + (self.maximumValue - self.minimumValue) * (touchLocation.x / self.frame.size.width);
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }

    [super touchesBegan:touches withEvent:event];
}

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {

    CGRect thumbRect = [super thumbRectForBounds:bounds trackRect:rect value:value];
    lastKnownThumbRect = thumbRect;
    return thumbRect;
}

Hope it helps someone :)

I have used this code. Get from: http://imagineric.ericd.net/2012/11/15/uislider-touch-to-set-value/

UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderTapped:)];
[slider addGestureRecognizer:gr];



- (void)sliderTapped:(UIGestureRecognizer *)g {
        UISlider* s = (UISlider*)g.view;
        if (s.highlighted)
            return; // tap on thumb, let slider deal with it
        CGPoint pt = [g locationInView: s];
        CGFloat percentage = pt.x / s.bounds.size.width;
        CGFloat delta = percentage * (s.maximumValue - s.minimumValue);
        CGFloat value = s.minimumValue + delta;
        [s setValue:value animated:YES];
    }

Hope this can help you.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!