更改iPhone UISlider条形图像

31
我在我的应用程序中使用了一个UISlider,但我想为它使用自定义的“外观和感觉”。我已经将滑块更改为自己的图像,但是否有一种方法也可以更改滑动条?我有一个滑动条图像,但不知道如何实现更改。
我已经找到了如何更改最大值和最小值图像,但没有找到如何更改滑动条本身的方法。

我已经尝试了[slider setMinimumTrackImage:forState:]方法,但是它使用图像并根据滑块的位置进行缩放。我想要的是在整个滑块上使用单个静态图像,而拇指在其上移动时保持不变。想象一下一个音量滑块,其中楔形表示相对音量的空和满。当滑块移动时,楔形保持不变。这就是我想做到的。谢谢! - Fogmeister
2
你能与用户分享自定义滑块图片的样本吗? - Ahsan
7个回答

60

你使用了-setMinimumTrackImage:forState:-setMaximumTrackImage:forState:方法是正确的。你错过的是你应该为它们提供可伸缩的UIImage,剩下的就会自动处理:

UIImage *sliderLeftTrackImage = [[UIImage imageNamed: @"SliderMin.png"] stretchableImageWithLeftCapWidth: 9 topCapHeight: 0];
UIImage *sliderRightTrackImage = [[UIImage imageNamed: @"SliderMax.png"] stretchableImageWithLeftCapWidth: 9 topCapHeight: 0];
[mySlider setMinimumTrackImage: sliderLeftTrackImage forState: UIControlStateNormal];
[mySlider setMaximumTrackImage: sliderRightTrackImage forState: UIControlStateNormal];

你可以在最小值和最大值部分使用相同的图像。


1
实际上,你的回答可以与Steve Melvin的回答合并,以形成完整的解决方案。 - Raptor
关于iOS 5的FYI,根据您的滑块图像,您可能会得到一些瓷砖化问题。 - jjxtra

25

最简单的解决方案是在控件后面渲染一个UIImage来代表轨道。可以使用以下代码更改拇指按钮:

[mySlider setThumbImage:[UIImage imageNamed:@"thumb_image.png"] forState:UIControlStateNormal];

这样做的一个副作用是,如果你不提供自己的轨道,那么轨迹将不会被渲染。而结合UIImage使用,则可以为你提供一个定制的UISlider,而无需子类化任何内容。


3
在iOS 5中,标准的UISlider似乎不再如此了,除非我错过了什么。 - Tim
4
[[UISlider appearanceWhenContainedIn:[self class], nil] setThumbImage:[UIImage...] forState:UIControlStateNormal]; 的翻译是:使用指定的图像设置滑块控件在正常状态下的滑块图片。如果需要实现“按下”效果,可以使用 UIControlStateHighlighted - Hari Honor

8

现代化的整合方式

如果您在Storyboard中定义了UISlider,则最好的样式化Slider的地方是在View的子类中。在awakeFromNib中,您可以更改按钮、左侧和右侧轨道。

iOS 5中已弃用此调用 stretchableImageWithLeftCapWidth:topCapHeight:

- (void)awakeFromNib
{
    [super awakeFromNib];

    UIImage *thumbImage = [UIImage imageNamed:@"slider-button"];
    [self.slider setThumbImage:thumbImage forState:UIControlStateNormal];

    UIImage *sliderLeftTrackImage = [UIImage imageNamed: @"slider-fill"];
    sliderLeftTrackImage = [sliderLeftTrackImage resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch];
    UIImage *sliderRightTrackImage = [UIImage imageNamed: @"slider-track"];
    sliderRightTrackImage = [sliderRightTrackImage resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch];
    [self.slider setMinimumTrackImage:sliderLeftTrackImage forState:UIControlStateNormal];
    [self.slider setMaximumTrackImage:sliderRightTrackImage forState:UIControlStateNormal];
}

8

这里提供一种方法,可以添加一个不被拉伸的轨道图片,从而可以像楼主所要求的那样,在背景中拥有楔形等形状:

Swift 3.0:

在此输入图片描述

let trackImg = image.resizableImage(withCapInsets: .zero, resizingMode: .tile)
slider.setMinimumTrackImage(trackImg, for: .normal)
slider.setMaximumTrackImage(trackImg, for: .normal)

重要提示:请确保您的滑块宽度与图像宽度完全相同!


4

stretchableImageWithLeftCapWidth:自iOS 5.0以来已被弃用。文档建议使用“capInsets”属性代替。以下是一个简单的方法:

创建三个图像,包括最小(左)轨道、最大(右)轨道和滑块。对于此示例,请假设最小和最大轨道图像为34p H x 18p W,如下所示:min track 和这个:enter image description here

像往常一样创建图像:

UIImage *thumbImage = [UIImage imageNamed:@"sliderThumb.png"];

UIImage *sliderMinTrackImage = [UIImage imageNamed: @"sliderMin.png"];

UIImage *sliderMaxTrackImage = [UIImage imageNamed: @"sliderMax.png"];

对于我展示的18个点宽的图像示例,左右内部点可以被拉伸以适应轨道,但两端应该有17个点宽不可拉伸的端点大小(因此称为capInsets):

sliderMinTrackImage = [sliderMinTrackImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 17, 0, 0)];

sliderMaxTrackImage = [sliderMaxTrackImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 17)];

然后像往常一样在UISlider上设置图像:

[slider setThumbImage:thumbImage forState:UIControlStateNormal];
[slider setMinimumTrackImage:sliderMinTrackImage forState:UIControlStateNormal];
[slider setMaximumTrackImage:sliderMaxTrackImage forState:UIControlStateNormal];

1

您需要继承UISlider并重写以下内容:

- (CGRect)trackRectForBounds:(CGRect)bounds

讨论:您不应直接调用此方法。如果您想自定义轨道矩形,则可以重写此方法并返回不同的矩形。返回的矩形用于在绘制过程中缩放轨道和拇指图像。

0
我正在做这个,但是在 iOS 5.1 中返回栏没有显示完美,但在 iOS 6.0 中它可以显示。
这是我的代码。
 UIImage *stetchLeftTrack = [[UIImage imageNamed:@"spectrum_horizontal_bar.png"]
                                stretchableImageWithLeftCapWidth:15.0 topCapHeight:0.0];
 UIImage *stetchRightTrack = [[UIImage imageNamed:@"spectrum_horizontal_bar.png"]
                                 stretchableImageWithLeftCapWidth:15.0 topCapHeight:0.0];
 [self.slider_Sprectrum setMinimumTrackImage:stetchLeftTrack forState:UIControlStateNormal];
 [self.slider_Sprectrum setMaximumTrackImage:stetchRightTrack forState:UIControlStateNormal];

@Hari Karam Singh [[UISlider appearanceWhenContainedIn:[self class], nil] setMinimumTrackImage:stetchLeftTrack forState:UIControlStateNormal]; [[UISlider appearanceWhenContainedIn:[self class], nil] setMaximumTrackImage:stetchRightTrack forState:UIControlStateNormal]; - Dk Kumar
嗨,Dk Kumar,我也在IOS 5中遇到了同样的问题,但在IOS 6中可以正常工作。我使用了两个相同的图像来表示最小值和最大值。拇指图像是一个小的透明发光图像。在IOS中,我可以看到拇指后面有一条线...你能帮忙解决一下你的情况是如何避免扭曲/拉伸的吗? - Dinakar
尝试移除stretchableImageWithLeftCapWidth...仅使用[UIImage imageNamed:@"spectrum_horizontal_bar.png"]...在滑动滑块时,它将开始显示正确的颜色。我在这里只注意到一个问题,即当您移动到最大和最小值时,它会更改滑块的左上角半径...我也在寻找解决方案。 - Ans
此外,stretchableImageWithLeftCapWidth在iOS 5中已被弃用,请使用resizableImageWithCapInsets作为替代。 - Ans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接