【问题标题】:Horizantal slider with tick marks on iOSiOS 上带有刻度线的水平滑块
【发布时间】:2012-03-01 00:55:35
【问题描述】:

我可以在 iOS 上实现带有刻度线的水平滑块吗?没有像 MacOS 这样的选项。

【问题讨论】:

  • 你必须自己编程; iOS 上的 UISlider 没有该功能。
  • 那么@CarlGoldsmith,你是如何做编程的?
  • @JohnK 问题是关于它的可能性,而不是方法;我的回答在一年前被接受了。
  • 看看我在 CocoaPods 上的 pod github.com/joamafer/JMMarkSlider

标签: ios xcode slider uislider


【解决方案1】:

来自@CarlGoldsmith - 您必须自己编程; iOS 上的 UISlider 没有该功能。

【讨论】:

    【解决方案2】:

    我实际上在我公司的网站上写了一个关于如何做到这一点的教程:

    http://fragmentlabs.com/blog/making-talking2trees-part-3-77

    对此的快速回答是我编写的自定义方法,上面的文章对此进行了解释:

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

    您基本上可以将此方法应用于位于 UISlider 后面的视图,并以适当的间隔创建刻度线。您可以通过修改 ticksDivider 变量来更改可见的刻度数。上面的示例为每个滑块值创建一个值,除非滑块的 maximumValue 属性大于 10(我的滑块值分别为 5、40 和 120),在这种情况下,我将值除以 10。

    您必须在xPos += offset+... 之后使用 offsetOffset 值和 float 值来说明拇指图像和滑块帽插入的宽度(因此拇指按钮似乎位于每个按钮的中心)。

    【讨论】:

    • 这个响应的好处在于它实际上提出了一个替代方案。不幸的是,拇指刻度对齐充其量是不完美的。必须摆弄参数(来源可疑)才能使对齐更加接近这一事实是 ad hoc 和不科学的(尤其是与 your code: 2.7/1.7 的差异)。毕竟,这应该是我们正在谈论的几何!需要根据实际参数进行研究,例如来自[slider thumbRectForBounds:trackRect:value:]。
    【解决方案3】:

    虽然 ctlockey 的解决方案确实有效,但我想要一些更简单的东西,但也允许拇指在用户释放它时捕捉到它最接近的任何刻度线。

    我的解决方案如下。它是 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];
    }
    

    【讨论】:

    • 上述实现在 iOS 6 中运行良好,但在 iOS 7+ 中,self.currentThumImage.size.width 的值不再可通过默认拇指图像访问。解决方案是,如果要访问图像的大小,则必须为拇指设置自定义图像。见:stackoverflow.com/questions/21313796/…
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多