将UIImage添加为UISlider的“Tick Marks”

时间:2015-05-25 00:32:08

标签: ios objective-c uiimage uislider

事先总结一下我的问题:我正在尝试确定滑块上的位置,我可以根据只知道UISlider的持续时间放置图像,并有一个循环的数组,相应地放置图像。

我一直在浏览UISlider上的Apple Docs,看来没有本地方法可以根据浮点数组在UISlider上添加“Tick marks”。 “刻度线”表示滑块上的线条,例如用于在擦洗器上放置广告的线条。这是一个可视化: enter image description here

现在,我有一个装满花车的阵列;浮动,我将使用它来根据UISlider的值删除刻度线。每次数组中浮点数的值都不同。我想遍历我的UISlider的.value属性,相应地删除UIImages。 UIImage是刻度标记,只是我创建的小资产。我无法弄清楚的是循环遍历UISlider的.value属性并根据UISlider的未来位置放置UIImage的逻辑。数组中浮点数的值每次都不同,所以我不能静态放置它们。有谁知道从哪里开始?我对Objective-C编程还是一个新手。

我知道可以利用在屏幕上检索滑块的起始X坐标,如下所示:

{{1}}

也许我可以在for循环中添加一个计算来代替放置图像。我不太确定从哪里开始......

2 个答案:

答案 0 :(得分:3)

方法trackRectForBounds和thumbRectForBounds是为UISlider的子类化提供的,但你可以直接调用它们,它们会预先设置你的tick中心。

- (float)sliderThumbCenter:(UISlider *)slider forValue:(float)value{
    CGRect trackRect = [slider trackRectForBounds:slider.bounds];
    CGRect thumbRect = [slider thumbRectForBounds:slider.bounds trackRect:trackRect value:value];
    CGFloat centerThumb = CGRectGetMidX(thumbRect);
    return centerThumb;
}

可能更容易做一个自定义视图来绘制轨道而不是图像视图,然后只需将滑块放在它上面并隐藏轨道。只需使滑块框架等于TickView的边界即可。真的,我认为UISlider子类会更好,但这有效!

@interface TickView : UIView
@property UIColor *tickColor;
@property int tickCount;
@property CGFloat tickHeight;
@property (weak) UISlider *slider;
@property float *ticks;
-(void)setTicks:(float *)ticks count:(int)tickCount;
@end


@implementation TickView{
    __weak UISlider *_slider;
}

-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.tickColor = [UIColor grayColor];
        self.backgroundColor = [UIColor clearColor];
        self.tickCount = 7;
        self.ticks = malloc(sizeof(float) * self.tickCount);
        self.tickHeight = 10;
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, self.tickColor.CGColor);

    CGContextBeginPath(context);
    CGFloat centerY = rect.size.height / 2;
    CGContextMoveToPoint(context, 0, centerY);
    CGContextAddLineToPoint(context, rect.size.width, centerY);
    CGFloat tickTop = centerY - self.tickHeight / 2;
    CGFloat tickBottom = centerY + self.tickHeight / 2;
    CGFloat tickX = 0;

    if (self.slider) {
        for (int i = 0; i < self.tickCount; i++) {
            tickX = [self sliderThumbCenter:self.slider forValue:self.ticks[i]];
            CGContextMoveToPoint(context, tickX, tickTop);
            CGContextAddLineToPoint(context, tickX, tickBottom);
        }
    }
    else{
        CGFloat tickSpacing = rect.size.width / (self.tickCount - 1);
        for (int i = 0; i < self.tickCount; i++) {
            CGContextMoveToPoint(context, tickX, tickTop);
            CGContextAddLineToPoint(context, tickX, tickBottom);
            tickX += tickSpacing;
        }
    }
    CGContextStrokePath(context);
}

-(void)setTicks:(float *)ticks count:(int)tickCount{
    free(_ticks);
    _ticks = malloc(sizeof(float) * tickCount);
    memcpy(_ticks, ticks, sizeof(float) * tickCount);
    _tickCount = tickCount;
    [self setNeedsDisplay];
}
- (float)sliderThumbCenter:(UISlider *)slider forValue:(float)value{
    CGRect trackRect = [slider trackRectForBounds:slider.bounds];
    CGRect thumbRect = [slider thumbRectForBounds:slider.bounds trackRect:trackRect value:value];
    CGFloat centerThumb = CGRectGetMidX(thumbRect);
    return centerThumb;
}
-(void)setSlider:(UISlider *)slider{
    _slider = slider;
}
-(UISlider *)slider{
    return _slider;
}
-(void)dealloc{
    free(_ticks);
}
@end

答案 1 :(得分:0)

我认为你将无法定位刻度线。但是,如果您的UISlider的父视图是&#34; view&#34;,您可以添加如下子视图:

[view addSubView:myTickView];

添加的子视图的位置由其frame属性决定,该属性位于父视图坐标空间中。 要删除视图,请执行以下操作:

[myTickView removeFromSuperView];

您还可以循环浏览刻度视图并更改帧,但这些更改将被设置为动画,因此如果您这样做,则刻度将显示为滑动,除非您关闭动画。