[英]Thumb image does not move to the edge of UISlider
即使它的值為最大值或最小值,拇指圖像也不會移動到邊緣。
有誰知道如何讓它一直移動到滑塊的邊緣?
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UISlider *slider;
@end
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIImage* sliderBarMinImage = [[UIImage imageNamed:@"slider_bar_3_min"] stretchableImageWithLeftCapWidth:8.0 topCapHeight:0.0];
UIImage* sliderBarImage = [[UIImage imageNamed:@"slider_bar_3_max"] stretchableImageWithLeftCapWidth:8.0 topCapHeight:0.0];
UIImage* sliderThumbImage= [[UIImage imageNamed:@"slider_thumb_3"] stretchableImageWithLeftCapWidth:8.0 topCapHeight:0.0];
[self.slider setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal];
[self.slider setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal];
[self.slider setThumbImage:sliderThumbImage forState:UIControlStateNormal];
}
@end
您所看到的是UISlider
顯然按設計工作。
默認情況下,在極值處,拇指的邊緣與軌道的邊緣對齊,而不是拇指的中心位於軌道的邊緣。 因此,如果您提供一個左右邊緣不透明的拇指圖像,這是一個問題,因為下面的軌道變得可見。
一種部分修復是覆蓋thumbRectForBounds(_:trackRect:value:)
,以便拇指的中心范圍跨越滑塊的寬度。 下面的代碼顯示了這一點:
class CenteredThumbSlider : UISlider {
override func thumbRectForBounds(bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect
{
let unadjustedThumbrect = super.thumbRectForBounds(bounds, trackRect: rect, value: value)
let thumbOffsetToApplyOnEachSide:CGFloat = unadjustedThumbrect.size.width / 2.0
let minOffsetToAdd = -thumbOffsetToApplyOnEachSide
let maxOffsetToAdd = thumbOffsetToApplyOnEachSide
let offsetForValue = minOffsetToAdd + (maxOffsetToAdd - minOffsetToAdd) * CGFloat(value / (self.maximumValue - self.minimumValue))
var origin = unadjustedThumbrect.origin
origin.x += offsetForValue
return CGRect(origin: origin, size: unadjustedThumbrect.size)
}
}
但是,我想說這只是部分修復,因為我不相信這也會修改拇指點擊區域的位置,所以上面的修復有一個不幸的副作用,就是讓拇指更不容易觸摸默認情況下,因為滑塊仍然會更靠近滑塊中心偵聽觸摸。
我最近不得不處理滑塊的自定義(子類),包括在滑塊上添加刻度線。 拇指圖像不以該值為中心,並且由於您替換了圖像,因此根據實現,它位於應有的位置。 為了做你想做的事,我不得不使用調整拇指圖像的位置
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
如果沒有更改,最受好評的答案對我不起作用。 這就是所做的——它是UISlider
的替代品:
class Slider: UISlider {
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float)->CGRect {
var thumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
//determine value dependent offset
var offsetForValue: CGFloat = 0
if value != 0 {offsetForValue = thumbRect.size.width * CGFloat(value / (self.maximumValue - self.minimumValue)) - ((value > 0) ? 2 : -2)}
//apply offset to thumb rect
thumbRect.origin.x += offsetForValue
return thumbRect
}
}
代替
[self.slider setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal];
[self.slider setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal];
[self.slider setThumbImage:sliderThumbImage forState:UIControlStateNormal];
嘗試像這樣設置外觀代理
[[UISlider appearance] setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal];
[[UISlider appearance] setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal];
[[UISlider appearance] setThumbImage:sliderThumbImage forState:UIControlStateNormal];
您會看到它已經移動到滑塊的邊緣。 這是因為拇指圖像滑塊有這樣的角落,所以你覺得它沒有移動到邊緣。
如果您想確認這一點,請在拇指圖像中嘗試使用方形圖像的相同代碼。
我希望它會幫助你。
我通過子類化 UISlider 創建了類似的滑塊。 在情節提要中,如果滑塊拇指未獲得觸摸事件,您可以設置高度約束以在運行時增加高度。
static float const SLIDER_OFFSET = 10.0;
//Get thumb rect for larger track rect than actual to move slider to edges
-(CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {
UIImage *image = self.currentThumbImage;
rect.origin.x -= SLIDER_OFFSET;
rect.size.width += (SLIDER_OFFSET*2);
CGRect thumbRect = [super thumbRectForBounds:bounds trackRect:rect value:value];
return CGRectMake(thumbRect.origin.x, rect.origin.y+2, image.size.width, image.size.height);
}
//Make track rect smaller than bounds
-(CGRect)trackRectForBounds:(CGRect)bounds {
bounds.origin.x += SLIDER_OFFSET;
bounds.size.width -= (SLIDER_OFFSET*2);
CGRect trackRect = [super trackRectForBounds:bounds];
return CGRectMake(trackRect.origin.x, trackRect.origin.y, trackRect.size.width, trackRect.size.height);
}
它可能不是最有效的,但它似乎工作正常。 這是在 Objective-C 中實現它的另一種簡單方法。 基本上,您將使用“pixelAdjustment”變量來獲得所需的滑塊。
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value: (float)value {
float multValue = value - 0.5;
float pixelAdjustment = 30; //This is the value you need to change depending on the size of the thumb image of your slider.
float xOriginDelta = (multValue * (bounds.size.width - pixelAdjustment));
CGRect adjustedRect = CGRectMake(bounds.origin.x + xOriginDelta, bounds.origin.y, bounds.size.width, bounds.size.height);
return adjustedRect;
}
我找到了一個更簡單的解決方案,它也有一個非常流暢的用戶體驗。
我基本上只是將.highlighted
圖像設置為與.normal
相同的值。 這是代碼。
seekBar.setThumbImage(thumbImage, for: .normal)
seekBar.setThumbImage(thumbImage, for: .highlighted)
所以我對這個問題的解決方案是讓滑塊Min Track和Max Track的顏色透明,然后在initWithCoder中繪制一個新的track,並在continueTrackingWithTouch中更新track的大小。
-(AnalogueSlider *)initWithCoder:(NSCoder *)coder :(NSArray *)labels {
self = [super initWithCoder:coder];
trackRect = [self trackRectForBounds:self.bounds];
thumbRect = [self thumbRectForBounds:self.bounds trackRect:trackRect value:self.value];
// drawn a new track
leftTrack = [[UIView alloc] initWithFrame:CGRectMake(trackRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, thumbRect.origin.x-thumbRect.size.width, trackRect.size.height)];
leftTrack.backgroundColor = [UIColor blueColor];
[self insertSubview:leftTrack belowSubview:self];
rightTrack = [[UIView alloc] initWithFrame:CGRectMake(thumbRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, trackRect.size.width-thumbRect.origin.x, trackRect.size.height)];
rightTrack.backgroundColor = [UIColor grayColor];
[self insertSubview:rightTrack belowSubview:self];
return self;
}
-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
thumbRect = [self thumbRectForBounds:self.bounds trackRect:trackRect value:self.value];
leftTrack.frame = CGRectMake(trackRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, thumbRect.origin.x-thumbRect.size.width, trackRect.size.height);
rightTrack.frame = CGRectMake(thumbRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, trackRect.size.width-thumbRect.origin.x, trackRect.size.height);
return [super continueTrackingWithTouch:touch withEvent:event];
}
這允許拇指圖像比軌道移動得更遠,因此拇指的中心位於軌道的末端。
最后:
我為這個問題應用了一個簡單的修復。
// Inside the custom USlider class
override public func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
let thumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
let xOffset: CGFloat = value > super.minimumValue ? 10 : -10 // Size of the custom thumb image
var origin = thumbRect.origin
origin.x += xOffset
return CGRect(origin: origin, size: thumbRect.size)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.