Setting tick marks for UISlider

2019-06-23 18:33发布

问题:

Is there any method for setting tick marks for UISlider. NSSlider has something called - (void)setNumberOfTickMarks:(NSInteger)numberOfTickMarks. But UISlider does not appear to have one.

What i want to do is get the slider values as 0,1,2,3,4 etc if say i set the min as 0 and max as 5. Now as such UISLider returns something like 0.0,0.1,0.2,0.3 etc 4.8,4.9,5.0 based on the example i gave above.

Any help??

回答1:

UISlider doesn't have any tickmarks.

To get the behaviour you specify you'll have to round the number returned by the slider to the nearest integer.

So when you start sliding, and the slider reports a value of 0.1 or 0.2, round that to 0. Until it hits 0.5, when you round up to 1.

Then when the slider stops sliding, you can set it's value to the number you rounded to, which will make the slider "snap" to that position, kind like snapping to a tick mark.

If you want visual tickmarks, you'll have to implement that yourself.



回答2:

Yeah I think that subclassing is the way to go. This is what I did:

TickSlider.h…

/**
 * A custom slider that allows the user to specify the number of tick marks.
 * It behaves just like the NSSlider with tick marks for a MacOS app.
 **/
@interface TickSlider : UISlider

/**
 * The number of tickmarks for the slider. No graphics will be draw in this
 * sublcass but the value of the slider will be rounded to the nearest tick
 * mark in the same way/behaviour as the NSSlider on a MacOS app. 
 * @discussion This value can be set as a UserDefinedAttribute in the xib file.
 **/
@property (nonatomic) NSInteger numberOfTickMarks;

@end

TickSlider.m…

#import "TickSlider.h"

@implementation TickSlider



 - (void)setValue:(float)value animated:(BOOL)animated {
    float updatedValue = value;

    if (self.numberOfTickMarks > 0) {
        updatedValue = MAX(self.minimumValue, MIN(value, self.maximumValue));

        if (self.numberOfTickMarks == 1) {
            updatedValue = (self.minimumValue + self.maximumValue) * 0.5f;
        }
        else {
            const int kNumberOfDivisions = (self.numberOfTickMarks - 1);
            const float kSliderRange = ([self maximumValue] - [self minimumValue]);
            const float kRangePerDivision = (kSliderRange / kNumberOfDivisions);
            const float currentTickMark = roundf(value / kRangePerDivision);
            updatedValue = (currentTickMark * kRangePerDivision);
        }
    }

    [super setValue:updatedValue animated:animated];
}


@end


回答3:

As above, casting to int makes the slider behave as if you where sliding next to the thumb. The above ticker code is interesting, allowing you to specify more "stop values" (ticks) as the maximum value setting.

If you need a simple "integer slider", rounding (value + 0.25) actually makes the slider behave quite nicely. This is the code I use:

@interface IntegerSlider : UISlider
@end

@implementation IntegerSlider

- (void) setValue: (float) value
         animated: (BOOL) animated
{
    value = roundf(value + 0.25);

    [super setValue: value
           animated: animated];
}

@end



回答4:

I just cast [slider value] to int to achieve this.