iPhone:Programming UISlider to position at clicked location
Asked Answered
P

6

7

How to set the slider to clicked position and get the slider value on the clicked location on UISlider in iPhone programming. i know we can drag the slider to that position but i dont want to do it. Can you please tel me how to set the slider to clicked position? Is this possible to do?

Parrakeet answered 24/5, 2010 at 6:21 Comment(0)
G
19

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];
}
Goddaughter answered 1/1, 2011 at 4:35 Comment(0)
E
12

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;
}
Enshrine answered 20/1, 2011 at 2:37 Comment(1)
if you used a custom -setThumbImage, use self.value = self.minimumValue + (self.maximumValue - self.minimumValue) * ((touchLocation.x - self.currentThumbImage.size.width/2)/ (self.frame.size.width-self.currentThumbImage.size.width)); in -touchesBegan.Hyperplasia
E
7

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

Enow answered 24/5, 2010 at 6:28 Comment(1)
Can you give a rough picture of how to introduce UITapGestureRecognizer into slider?Parrakeet
T
3

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
    }
}
Theodolite answered 14/7, 2017 at 20:9 Comment(0)
T
1

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 :)

Tildy answered 12/9, 2013 at 17:4 Comment(0)
P
0

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.

Placidia answered 31/10, 2014 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.