Complete Playground source available here
如果您继承UISlider,您可以覆盖thumbRect(forBounds:trackRect:value:) 方法,该方法允许您调整显示拇指图像的矩形。这样做,并使其定位拇指图像它的中心在轨道上的相应点上。
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
let superThumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
let valueAsDecimalFraction = value == minimumValue ? 0 : (value - minimumValue)/(maximumValue - minimumValue)
let valueAsDecimalFractionOfMinusOneToOne = (valueAsDecimalFraction*2 - 1)/2
let xOffset = CGFloat(valueAsDecimalFractionOfMinusOneToOne) * superThumbRect.width
return CGRect(
x: superThumbRect.origin.x + xOffset,
y: superThumbRect.origin.y,
width: superThumbRect.size.width,
height: superThumbRect.size.height)
}
一旦您覆盖了thumbRect(forBounds:trackRect:value:),您将看到拇指图像现在具有正确的行为,除了现在当滑块处于最小值或最大值时它挂在视图之外。要解决此问题,请覆盖 trackRect(forBounds:) 方法,以便将轨道填充一些允许拇指图像保持在滑块范围内的值。
let padding = CGFloat(18)
override func trackRect(forBounds bounds: CGRect) -> CGRect {
let superTrackRect = super.trackRect(forBounds: bounds)
return CGRect(
x: superTrackRect.origin.x + padding,
y: superTrackRect.origin.y,
width: superTrackRect.size.width - padding*2,
height: superTrackRect.size.height)
}
您可能很难使用UIStackView 定位UILabels - 标签的中心点不会位于正确的位置。相反,使用相对于滑块的约束来布局标签。
// Assuming labels: [UILabel], and a value of thumbIndent
override func viewWillLayoutSubviews() {
let labelConstraints = labels.enumerated().map { (i, label) -> [NSLayoutConstraint] in
let pct = CGFloat(i)/CGFloat(labels.count-1)
let centerX = (view.bounds.size.width-2*thumbIndent) * pct + thumbIndent
return [
label.centerXAnchor.constraint(equalTo: slider.leftAnchor, constant: centerX),
label.bottomAnchor.constraint(equalTo: slider.topAnchor, constant: 0),
]
}.flatMap { $0 }
.
.
.
}