拇指图像不会移动到UISlider的边缘

时间:2014-02-03 06:22:25

标签: ios slider

拇指图像即使在值为最大值或最小值时也不会移动到边缘。

有谁知道如何让它一直移动到滑块的边缘?

enter image description here

@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

9 个答案:

答案 0 :(得分:10)

你看到的是SELECT显然是按设计工作的。

默认情况下,在极值处,拇指的边缘与轨道的边缘对齐,而不是拇指的中心位于轨道的边缘。因此,如果您提供左右边缘不是不透明的拇指图像,则会出现问题,因为此后下面的轨迹变得可见。

一个部分修复方法是覆盖UISlider,以便大拇指'中心的范围跨越滑块的宽度。下面的代码显示了这一点:

thumbRectForBounds(_:trackRect:value:)

但是,我会说这只是部分修复,因为我不相信这也会修改拇指的分接区域的位置,所以上面的这个修复有不幸的一面 - 默认情况下,使拇指更容易触摸的效果,因为滑块仍然会更倾向于触摸滑块中心的触摸。

答案 1 :(得分:2)

我最近不得不处理滑块(子类)的自定义,包括在滑块上添加标记。拇指图像不是以值为中心,因为您替换了图像,它根据实现位于应该位于的位置。 为了做你想做的事情我必须使用

调整拇指图像的位置
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value

答案 2 :(得分:1)

而不是

[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];

答案 3 :(得分:0)

你看到它已经移动到Slider的边缘了。因为拇指图像滑块有这样的角落,所以你感觉它不会移动到边缘。

如果您想确认这一点,请在拇指图像中使用方形图像尝试相同的代码。

我希望它会对你有所帮助。

答案 4 :(得分:0)

我通过继承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);
}

答案 5 :(得分:0)

大多数赞成的答案对我没有任何改变。这是做了什么 - 它取代了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
    }
}

答案 6 :(得分:0)

它可能不是最有效的,但似乎工作正常。这是在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;
}

答案 7 :(得分:0)

我找到了一个更简单的解决方案,它也具有相当流畅的用户体验。

我基本上只是将.highlighted图像设置为与.normal相同的值。这是代码。

    seekBar.setThumbImage(thumbImage, for: .normal)
    seekBar.setThumbImage(thumbImage, for: .highlighted)

答案 8 :(得分:0)

所以我对这个问题的解决方案是使滑块“最小轨道”和“最大轨道”的颜色透明,然后在initWithCoder中绘制新轨道,并在continueTrackingWithTouch中更新轨道的大小。

-(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];
}

这允许拇指图像比轨迹移动得更远,因此拇指的中心位于轨迹的末端。

near end

最后:

at end