簡體   English   中英

拇指圖像不會移動到 UISlider 的邊緣

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM