同时在 2019 年和 iOS 12 存在该错误
一个老问题,仍然是相关问题。因此,虽然接受的答案正常工作,但它有一个小而重要的问题 - 拇指触摸区域越来越小,而在大多数情况下增加可触摸区域会导致新的跳跃(已尝试覆盖 thumbRect(forBounds 和 beginTracking 方法)
让我们修复它!
所以解决方案没有那么复杂但有点不方便(需要一些图片资源),还是比重新实现自己的 Slider 容易
这个类的目的是消除 UIKit 错误,这是
在敲击时跳跃拇指。
主要的技巧是用一些图像替换原始拇指
其他代码是扩展攻丝区域,即:
1) 设置一个带有一些侧边 alpha 偏移的图像,即较大矩形中的一个圆圈
setThumbImage(thumb, for: .normal)
2) 更大的图像意味着更大的拇指,结果跟踪最小值和最大值
在图像的 alpha 区域下可见。所以下一步是设置最小和最大轨道
分别在左右两侧跟踪的图像,
setMinimumTrackImage(anImage, for: .normal)
setMaximumTrackImage(maxSliderImage, for: .normal)
但图像也有一些 alpha 区域需要“隐藏”轨道
拇指的两侧(具有完全可见的最小/最大值)。
4)虽然我们有更大的拇指和轨道视觉上减少(相对于滑块边界宽度)
需要通过覆盖 trackRect(forBounds 方法来增加轨道的可见部分。
我们不会有超出滑块边界的轨道,因为最小/最大图像的一部分是透明的
5)作为目标之一是增加拇指的触摸区域需要覆盖
point(inside point:, with event:) 方法在侧面制作可触摸区域
PS:不要忘记在 xcassets 中设置 min 和 max 滑块轨道属性:
1)切片水平和左/右插图
2) 拉伸技术
class Slider: UISlider {
/// The value is distance between an image edge and thumb,
/// Assume that's an image scheme: [...o...] so 3 dots here is imageSideOffset, where 'o' is a thumb
/// as we want to hide that zone
private let imageSideOffset: CGFloat = 30
override func awakeFromNib() {
super.awakeFromNib()
if let thumb = UIImage(named: "slider_thumb"),
let minSliderImage = UIImage(named: "min_slider_track"),
let maxSliderImage = UIImage(named: "max_slider_track") {
setThumbImage(thumb, for: .normal)
setMinimumTrackImage(minSliderImage, for: .normal)
setMaximumTrackImage(maxSliderImage, for: .normal)
clipsToBounds = true
} else {
assertionFailure("failed to load slider's images")
}
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return bounds.insetBy(dx: -imageSideOffset, dy: 0).contains(point)
}
override func trackRect(forBounds bounds: CGRect) -> CGRect {
let superRect = super.trackRect(forBounds: bounds)
guard let _ = self.thumbImage(for: .normal) else {
return superRect
}
return superRect.insetBy(dx: -imageSideOffset, dy: 0)
}
}