将 UIImage 作为“刻度线”添加到 UISlider
Posted
技术标签:
【中文标题】将 UIImage 作为“刻度线”添加到 UISlider【英文标题】:Adding UIImage's as "Tick Marks" to UISlider 【发布时间】:2015-05-25 00:32:07 【问题描述】:预先总结一下我的问题:我正在尝试根据仅知道 UISlider 的持续时间来确定可以在滑块上放置图像的位置,并有一组时间循环遍历,相应地放置图像。
我一直在阅读有关 UISlider 的 Apple Docs,似乎没有本地方法可以根据浮点数组在 UISlider 上添加“刻度线”。 “刻度线”是指滑块上的线条,例如用于将广告放置在洗涤器上的线条。这是一个可视化:
现在,我有一个充满浮点数的数组;根据 UISlider 的值,我将使用浮动来删除刻度线。数组中浮点数的值每次都会不同。我想遍历我的 UISlider 的 .value 属性,相应地删除 UIImages。 UIImage 是我创建的小 png 资产的刻度线。我无法弄清楚的是循环遍历 UISlider 的 .value 属性并根据 UISlider 的未来位置放置 UIImage 背后的逻辑。数组中浮点数的值每次都会不同,所以我不能静态放置它们。有谁知道从哪里开始?我对 Objective-C 编程还是有点陌生。
我知道可以利用检索滑块在屏幕上的起始 X 坐标,如下所示:
- (float)xPositionFromSliderValue:(UISlider *)aSlider;
float sliderRange = aSlider.frame.size.width - aSlider.currentThumbImage.size.width;
float sliderOrigin = aSlider.frame.origin.x + (aSlider.currentThumbImage.size.width / 2.0);
float sliderValueToPixels = (((aSlider.value-aSlider.minimumValue)/(aSlider.maximumValue-aSlider.minimumValue)) * sliderRange) + sliderOrigin);
return sliderValueToPixels;
也许我可以在 for 循环中添加一个计算来根据该计算放置图像。我只是不太确定从哪里开始......
【问题讨论】:
UISlider 没有持续时间属性。你是说价值属性吗?如果是这样,请编辑您的问题。 是的,我的意思是持续时间,我的变量的名称是持续时间。 OP 已编辑。 另外,滑块的宽度与其最小值或最大值无关。它由滑块的 frame 属性决定。但是,它们无法获取滑块开始和结束的确切位置。 @MichaelL 没错,我更新了 OP,其中包含可以用来代替它的潜在代码。 【参考方案1】:trackRectForBounds 和 thumbRectForBounds 方法是为 UISlider 子类化提供的,但您可以直接调用它们,它们会提前获取刻度中心。
- (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
【讨论】:
感谢您的意见!在您发布的第一种方法中,似乎调用会移动洗涤器,不是吗?我要完成的主要目标是根据只知道 UISlider 的持续时间来确定我可以在滑块上放置图像的位置,并有一系列时间来循环放置它们。 不,它不会移动拇指。它的目的是让拇指中心的 x 偏移量达到某个值。因此,如果您的滑块从 0 -> 10,并且您想知道拇指 将 位于 7 的位置(相对于滑块的框架,您将获得像 thisCGFloat xOffset = [self sliderThumbCenter:slider forValue:7];
这样的 x 偏移量。您可以通过将 7 替换为 slider.value
来获得当前拇指中心 x 偏移量。【参考方案2】:
我认为您在定位刻度线时会遇到问题。但是,如果您的 UISlider 的父视图是“视图”,您可以像这样添加一个子视图:
[view addSubView:myTickView];
添加的子视图的位置由它的frame属性决定,在父视图坐标空间中。 要删除视图,请执行以下操作:
[myTickView removeFromSuperView];
您还可以循环浏览刻度视图并更改帧,但这些更改将被动画化,因此如果您这样做,刻度会显示为滑动,除非您关闭动画。
【讨论】:
以上是关于将 UIImage 作为“刻度线”添加到 UISlider的主要内容,如果未能解决你的问题,请参考以下文章
在 matplotlib imshow 中调整网格线和刻度线
将 UIImage 视图作为子视图添加到 UIView 的实例