Article / 2026/05/29
UISlider 完整API指南
UISlider 是 iOS 开发中用于选择数值范围的控件,常用于音量控制、进度条、设置数值等场景。
🚀 UISlider 完整API指南
UISlider 是 iOS 开发中用于选择数值范围的控件,常用于音量控制、进度条、设置数值等场景。
基础属性
数值相关属性
// 当前值
var value: Float { get set }
// 最小值(默认 0.0)
var minimumValue: Float { get set }
// 最大值(默认 1.0)
var maximumValue: Float { get set }
// 是否连续触发事件(默认 true)
var isContinuous: Bool { get set }
交互状态属性
// 是否正在被用户拖拽(只读)
var isTracking: Bool { get }
// 当前的触摸对象(只读)
var currentTouch: UITouch? { get }
// 是否启用用户交互(继承自 UIControl)
var isEnabled: Bool { get set }
// 是否高亮状态(继承自 UIControl)
var isHighlighted: Bool { get set }
// 是否被选中(继承自 UIControl)
var isSelected: Bool { get set }
外观相关属性
// 滑块颜色(滑块左边部分的颜色)
var minimumTrackTintColor: UIColor? { get set }
// 滑道颜色(滑块右边部分的颜色)
var maximumTrackTintColor: UIColor? { get set }
// 滑块按钮颜色
var thumbTintColor: UIColor? { get set }
图片相关属性
// 左侧图标
var minimumValueImage: UIImage? { get set }
// 右侧图标
var maximumValueImage: UIImage? { get set }
核心方法
设置数值
// 设置值(带动画)
func setValue(_ value: Float, animated: Bool)
// 示例
slider.setValue(0.5, animated: true)
自定义滑块外观
// 设置滑块按钮图片
func setThumbImage(_ image: UIImage?, for state: UIControl.State)
// 设置左侧滑道图片
func setMinimumTrackImage(_ image: UIImage?, for state: UIControl.State)
// 设置右侧滑道图片
func setMaximumTrackImage(_ image: UIImage?, for state: UIControl.State)
// 示例
slider.setThumbImage(UIImage(named: "custom_thumb"), for: .normal)
slider.setMinimumTrackImage(UIImage(named: "min_track"), for: .normal)
slider.setMaximumTrackImage(UIImage(named: "max_track"), for: .normal)
获取自定义图片
// 获取滑块按钮图片
func thumbImage(for state: UIControl.State) -> UIImage?
// 获取左侧滑道图片
func minimumTrackImage(for state: UIControl.State) -> UIImage?
// 获取右侧滑道图片
func maximumTrackImage(for state: UIControl.State) -> UIImage?
获取组件位置和尺寸
// 获取滑道区域
func trackRect(forBounds bounds: CGRect) -> CGRect
// 获取滑块按钮区域
func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect
// 示例
let trackFrame = slider.trackRect(forBounds: slider.bounds)
let thumbFrame = slider.thumbRect(forBounds: slider.bounds,
trackRect: trackFrame,
value: slider.value)
触摸和交互方法
// 开始跟踪触摸(可重写)
func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool
// 继续跟踪触摸(可重写)
func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool
// 结束跟踪触摸(可重写)
func endTracking(_ touch: UITouch?, with event: UIEvent?)
// 取消跟踪触摸(可重写)
func cancelTracking(with event: UIEvent?)
// 检查点是否在控件内(可重写)
func point(_ point: CGPoint, inside view: UIView, with event: UIEvent?) -> Bool
可访问性属性
// 可访问性标签
var accessibilityLabel: String? { get set }
// 可访问性值
var accessibilityValue: String? { get set }
// 可访问性提示
var accessibilityHint: String? { get set }
// 可访问性特征
var accessibilityTraits: UIAccessibilityTraits { get set }
// 可访问性增量
func accessibilityIncrement()
// 可访问性减量
func accessibilityDecrement()
事件处理
监听数值变化
// 添加事件监听
slider.addTarget(self,
action: #selector(sliderValueChanged(_:)),
for: .valueChanged)
@objc func sliderValueChanged(_ sender: UISlider) {
print("当前值: \(sender.value)")
}
// 监听拖拽开始
slider.addTarget(self,
action: #selector(sliderTouchDown(_:)),
for: .touchDown)
// 监听拖拽结束
slider.addTarget(self,
action: #selector(sliderTouchUp(_:)),
for: [.touchUpInside, .touchUpOutside])
常用控制事件
.valueChanged // 值改变时触发
.touchDown // 开始触摸时触发
.touchUpInside // 在控件内部释放时触发
.touchUpOutside // 在控件外部释放时触发
.touchCancel // 触摸被取消时触发
完整使用示例
基础音量控制器
class VolumeController: UIViewController {
@IBOutlet weak var volumeSlider: UISlider!
@IBOutlet weak var volumeLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
setupVolumeSlider()
}
private func setupVolumeSlider() {
// 设置数值范围
volumeSlider.minimumValue = 0.0
volumeSlider.maximumValue = 1.0
volumeSlider.value = 0.5
// 设置外观
volumeSlider.minimumTrackTintColor = .systemBlue
volumeSlider.maximumTrackTintColor = .systemGray
volumeSlider.thumbTintColor = .white
// 设置图标
volumeSlider.minimumValueImage = UIImage(systemName: "speaker.fill")
volumeSlider.maximumValueImage = UIImage(systemName: "speaker.wave.3.fill")
// 监听变化
volumeSlider.addTarget(self,
action: #selector(volumeChanged(_:)),
for: .valueChanged)
// 初始化标签
updateVolumeLabel()
}
@objc private func volumeChanged(_ sender: UISlider) {
updateVolumeLabel()
// 设置实际音量
// AVAudioSession.sharedInstance().outputVolume = sender.value
}
private func updateVolumeLabel() {
volumeLabel.text = String(format: "%.0f%%", volumeSlider.value * 100)
}
}
视频播放进度条
class VideoProgressSlider: UISlider {
override func awakeFromNib() {
super.awakeFromNib()
setupAppearance()
}
private func setupAppearance() {
// 设置进度条颜色
minimumTrackTintColor = .red
maximumTrackTintColor = UIColor.white.withAlphaComponent(0.3)
thumbTintColor = .red
// 自定义滑块大小
setThumbImage(createThumbImage(), for: .normal)
// 设置范围
minimumValue = 0.0
maximumValue = 1.0
}
private func createThumbImage() -> UIImage? {
let size = CGSize(width: 20, height: 20)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(UIColor.red.cgColor)
context?.fillEllipse(in: CGRect(origin: .zero, size: size))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
自定义滑块样式
extension UISlider {
// 设置圆形滑块
func setCircularThumb(radius: CGFloat, color: UIColor) {
let thumbImage = createCircularImage(radius: radius, color: color)
setThumbImage(thumbImage, for: .normal)
setThumbImage(thumbImage, for: .highlighted)
}
// 设置滑道高度
func setTrackHeight(_ height: CGFloat) {
let trackImage = createTrackImage(height: height, color: .clear)
setMinimumTrackImage(trackImage, for: .normal)
setMaximumTrackImage(trackImage, for: .normal)
}
private func createCircularImage(radius: CGFloat, color: UIColor) -> UIImage? {
let size = CGSize(width: radius * 2, height: radius * 2)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fillEllipse(in: CGRect(origin: .zero, size: size))
// 添加阴影
context?.setShadow(offset: CGSize(width: 0, height: 2), blur: 4, color: UIColor.black.withAlphaComponent(0.3).cgColor)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
private func createTrackImage(height: CGFloat, color: UIColor) -> UIImage? {
let size = CGSize(width: 1, height: height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fill(CGRect(origin: .zero, size: size))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image?.resizableImage(withCapInsets: .zero)
}
}
补充的重要属性和方法
继承自 UIControl 的属性
// 控件状态
var state: UIControl.State { get }
// 内容垂直对齐
var contentVerticalAlignment: UIControl.ContentVerticalAlignment { get set }
// 内容水平对齐
var contentHorizontalAlignment: UIControl.ContentHorizontalAlignment { get set }
// 所有触摸对象
var allTouches: Set<UITouch>? { get }
// 所有事件
var allEvents: Set<UIControl.Event> { get }
语义化内容属性
// 语义化内容属性(支持从右到左的语言)
var semanticContentAttribute: UISemanticContentAttribute { get set }
// 有效的用户界面布局方向
var effectiveUserInterfaceLayoutDirection: UIUserInterfaceLayoutDirection { get }
外观代理属性
// 外观代理设置(类方法)
class func appearance() -> Self
class func appearance(whenContainedInInstancesOf containerTypes: [UIAppearanceContainer.Type]) -> Self
// 示例:全局设置所有 UISlider 的外观
UISlider.appearance().minimumTrackTintColor = .systemBlue
UISlider.appearance().maximumTrackTintColor = .systemGray
UISlider.appearance().thumbTintColor = .white
层级和变换属性
// 图层属性(继承自 UIView)
var layer: CALayer { get }
// 变换矩阵
var transform: CGAffineTransform { get set }
// 用户交互
var isUserInteractionEnabled: Bool { get set }
// 是否支持多点触控
var isMultipleTouchEnabled: Bool { get set }
// 是否独占触摸
var isExclusiveTouch: Bool { get set }
1. 离散值滑块
class DiscreteSlider: UISlider {
var stepValue: Float = 1.0
override func setValue(_ value: Float, animated: Bool) {
let roundedValue = round(value / stepValue) * stepValue
super.setValue(roundedValue, animated: animated)
}
override var value: Float {
get {
return super.value
}
set {
let roundedValue = round(newValue / stepValue) * stepValue
super.value = roundedValue
}
}
}
2. 双向滑块(范围选择)
class RangeSlider: UIView {
private let trackLayer = CALayer()
private let lowerThumbLayer = CALayer()
private let upperThumbLayer = CALayer()
var minimumValue: Float = 0.0
var maximumValue: Float = 1.0
var lowerValue: Float = 0.2
var upperValue: Float = 0.8
// 实现双向滑块逻辑...
}
3. 垂直滑块
class VerticalSlider: UISlider {
override init(frame: CGRect) {
super.init(frame: frame)
transform = CGAffineTransform(rotationAngle: -CGFloat.pi/2)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
transform = CGAffineTransform(rotationAngle: -CGFloat.pi/2)
}
}
常见问题和解决方案
1. 滑块拖拽时不够灵敏
// 增加滑块的触摸区域
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
let thumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
return thumbRect.insetBy(dx: -10, dy: -10) // 扩大触摸区域
}
2. 自定义滑道圆角
override func trackRect(forBounds bounds: CGRect) -> CGRect {
var trackRect = super.trackRect(forBounds: bounds)
trackRect.size.height = 8.0 // 自定义滑道高度
return trackRect
}
override func layoutSubviews() {
super.layoutSubviews()
// 设置圆角
layer.cornerRadius = 4.0
layer.masksToBounds = true
}
3. 监听拖拽状态
private var isTracking = false
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
isTracking = true
return super.beginTracking(touch, with: event)
}
override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
isTracking = false
super.endTracking(touch, with: event)
// 拖拽结束后的处理
print("拖拽结束,最终值: \(value)")
}
最佳实践
- 性能优化: 对于连续更新的场景,考虑使用
isContinuous = false来减少事件触发频率 - 可访问性: 为滑块设置合适的
accessibilityLabel和accessibilityValue - 用户体验: 提供视觉反馈,比如haptic feedback或声音提示
- 数值验证: 始终验证滑块的数值范围,避免越界问题
// 可访问性设置
slider.accessibilityLabel = "音量控制"
slider.accessibilityValue = "\(Int(slider.value * 100))%"
// Haptic反馈
let impactFeedback = UIImpactFeedbackGenerator(style: .light)
impactFeedback.impactOccurred()
Giscus 未启用:请在
src/site.config.ts中配置 repoId 与 categoryId。