2015-05-25 81 views
1

事先總結我的問題:我試圖確定滑塊上哪裏可以放置圖像的基礎是隻知道UISlider的持續時間,並且有一個循環次數通過,相應地放置圖像。將UIImage作爲「Tick Marks」添加到UISlider

我一直在閱讀UISlider上的Apple文檔,它似乎沒有原生的方式來在基於浮點數組的UISlider上添加「刻度線」。 「標記」是指滑塊上的含義,例如用於在洗滌器上放置廣告的線條。這裏是一個可視化: enter image description here

現在,我有一個數組完整的浮動;浮動我將用於根據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.minimumValu‌​e)) * sliderRange) + sliderOrigin); 

    return sliderValueToPixels; 
} 

也許我可以在計算在按照增加對循環放置圖像相反。我只是不太確定哪裏開始在這裏...

+0

UISliders沒有持續時間屬性。你的意思是價值財產?如果是這樣,請編輯您的問題。 –

+0

是的,我的意思是持續時間,我的變量的名稱是持續時間。 OP編輯。 – John

+0

此外,滑塊的寬度與其最小值或最大值無關。它由滑塊的框架屬性決定。但是,他們無法獲得滑塊開始和結束的確切位置。 –

回答

3

爲UISlider的子類提供trackRectForBounds和thumbRectForBounds方法,但您可以直接調用它們,並且它們將首先獲得您的刻度中心。

- (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 
+0

謝謝您的輸入!在你發佈的第一個方法中,似乎調用它會移動洗滌器,不是嗎?我試圖完成的主要目標是確定在滑塊上的哪個位置可以基於僅知道UISlider的持續時間來放置圖像,並通過放置它們來循環播放一系列時間。 – John

+1

不,它不會移動拇指。它的目的是讓拇指中心的x偏移量達到一定值。因此,如果你的滑塊從0到> 10,並且你想知道拇指*將在7的位置(相對於滑塊的框架,你將得到像這樣的x偏移量)[CGFloat xOffset = [self sliderThumbCenter:slider forValue :7];'你可以通過用'slider.value'代替7來得到當前的拇指中心x偏移量 – dave234

+0

這非常酷,非常感謝你的洞察! – John

0

我認爲你將有麻煩定位刻度線。然而,如果你UISlider的父視圖是「視圖」中,添加一個子視圖這樣的:

[view addSubView:myTickView]; 

添加子視圖的位置由它的框架屬性,這是在父母的視圖座標空間的確定。 要刪除一個視圖,你這樣做:

[myTickView removeFromSuperView]; 

您也可以遍歷您剔的意見,然後在那裏框架,但這些變化將是動畫,所以蜱會出現下滑,如果你這樣做,除非你關閉動畫。