xcode iOS 上带有刻度线的水平滑块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9195868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Horizantal slider with tick marks on iOS
提问by Eugene Trapeznikov
Can i realise a horizontal slider with tick marks on iOS? There is not such option like in MacOS.
我可以在 iOS 上实现带有刻度线的水平滑块吗?没有像 MacOS 这样的选项。
采纳答案by Eugene Trapeznikov
From @CarlGoldsmith - You'd have to program that yourself; UISliders on iOS don't have that functionality.
来自@CarlGoldsmith - 你必须自己编程;iOS 上的 UISliders 没有这个功能。
回答by ctlockey
I actually wrote a tutorial on how to do this on my company's website:
我实际上在我公司的网站上写了一个关于如何做到这一点的教程:
http://fragmentlabs.com/blog/making-talking2trees-part-3-77
http://fragmentlabs.com/blog/making-talking2trees-part-3-77
The quick answer for this is a custom method I wrote, and which is explained in the article above:
对此的快速答案是我编写的自定义方法,并在上面的文章中进行了解释:
-(UIView*)tickMarksViewForSlider:(UISlider*)slider View:(UIView *)view
{
// set up vars
int ticksDivider = (slider.maximumValue > 10) ? 10 : 1;
int ticks = (int) slider.maximumValue / ticksDivider;
int sliderWidth = 364;
float offsetOffset = (ticks < 10) ? 1.7 : 1.1;
offsetOffset = (ticks > 10) ? 0 : offsetOffset;
float offset = sliderWidth / ticks - offsetOffset;
float xPos = 0;
// initialize view to return
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y+1,
slider.frame.size.width, slider.frame.size.height);
view.backgroundColor = [UIColor clearColor];
// make a UIImageView with tick for each tick in the slider
for (int i=0; i < ticks; i++)
{
if (i == 0) {
xPos += offset+5.25;
}
else
{
UIView *tick = [[UIView alloc] initWithFrame:CGRectMake(xPos, 3, 2, 16)];
tick.backgroundColor = [UIColor colorWithWhite:0.7 alpha:1];
tick.layer.shadowColor = [[UIColor whiteColor] CGColor];
tick.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
tick.layer.shadowOpacity = 1.0f;
tick.layer.shadowRadius = 0.0f;
[view insertSubview:tick belowSubview:slider];
xPos += offset - 0.4;
}
}
// return the view
return view;
}
You'd basically apply this method to a view that sits behind your UISlider, and it creates the tick marks at the appropriate intervals. You can change how many ticks are visible by modifying the ticksDivider variable. The above example creates one per slider value unless the slider's maximumValue property is greater than 10 (my sliders had values of 5, 40 and 120), in which case I divided the value by 10.
您基本上将此方法应用于位于 UISlider 后面的视图,并以适当的间隔创建刻度线。您可以通过修改 ticksDivider 变量来更改可见的刻度数。上面的示例为每个滑块值创建一个值,除非滑块的 maximumValue 属性大于 10(我的滑块的值为 5、40 和 120),在这种情况下,我将值除以 10。
You have to play with the offsetOffset value and the float value after xPos += offset+...
to account for the width of your thumb image and slider cap insets (so the thumb button appears to be centered over each).
您必须在之后使用 offsetOffset 值和 float 值xPos += offset+...
来考虑拇指图像和滑块帽插图的宽度(因此拇指按钮似乎位于每个按钮的中心)。
回答by vaticRite
While ctlockey's solution certainly works, I wanted something simpler but also that allowed the thumb to snap to whichever tick mark it is closest to when the user releases it.
虽然 ctlockkey 的解决方案确实有效,但我想要一些更简单的东西,但也允许拇指在用户释放时捕捉到它最接近的刻度线。
My solution is below. It is a subclass of UISlider that only overrides two methods. It is bare bones but would be a foundation for a more complex version.
我的解决方案如下。它是 UISlider 的一个子类,只覆盖了两个方法。它是裸露的骨头,但将是更复杂版本的基础。
-(void)endTrackingWithTouch:(UITouch *)touch
withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
if (self.value != floorf(self.value))
{
CGFloat roundedFloat = (float)roundf(self.value);
[self setValue:roundedFloat animated:YES];
}
}
-(void)drawRect:(CGRect)rect
{
CGFloat thumbOffset = self.currentThumbImage.size.width / 2.0f;
NSInteger numberOfTicksToDraw = roundf(self.maximumValue - self.minimumValue) + 1;
CGFloat distMinTickToMax = self.frame.size.width - (2 * thumbOffset);
CGFloat distBetweenTicks = distMinTickToMax / ((float)numberOfTicksToDraw - 1);
CGFloat xTickMarkPosition = thumbOffset; //will change as tick marks are drawn across slider
CGFloat yTickMarkStartingPosition = self.frame.size.height / 2; //will not change
CGFloat yTickMarkEndingPosition = self.frame.size.height; //will not change
UIBezierPath *tickPath = [UIBezierPath bezierPath];
for (int i = 0; i < numberOfTicksToDraw; i++)
{
[tickPath moveToPoint:CGPointMake(xTickMarkPosition, yTickMarkStartingPosition)];
[tickPath addLineToPoint:CGPointMake(xTickMarkPosition, yTickMarkEndingPosition)];
xTickMarkPosition += distBetweenTicks;
}
[tickPath stroke];
}