iOS - UISlider 在第一次触摸时跳跃
Posted
技术标签:
【中文标题】iOS - UISlider 在第一次触摸时跳跃【英文标题】:iOS - UISlider jumps on first touch 【发布时间】:2014-04-05 19:27:29 【问题描述】:我已将UISlider
添加到我正在使用 Xcode 5.1 开发的 ios 应用程序中,但我无法摆脱以下烦人的行为。当我第一次触摸拇指时,它会轻微跳跃。
这是一个详细说明行为的快速示例。
当滑块最初位于中心的左侧时(例如,在最小值处),它会跳到右侧。如果我在 iOS 模拟器中运行该应用程序,拇指在第一次触摸时会跳动而没有任何拖动。拇指总是跳向轨道的中心。它唯一不跳跃的时候是它在轨道的精确中心。即使滑块未连接到任何东西,也会出现此行为。
有什么办法可以禁用它?
【问题讨论】:
@ipinak 很明显。不需要代码。 这纯粹是模拟器现象吗?你有一个方便的设备可以试一试吗?如果它只是一个模拟器的东西,你应该笑着忽略它。鼠标光标不是大胖手指,可能是模拟器在做某种补偿。 不,当我在 iPad 上测试时也会发生这种情况。我刚才提到模拟器是为了强调“跳跃”不是我无意中在 ipad 屏幕上移动手指的结果。 好的,这个是已知的,有解决办法:***.com/questions/20903317/… 太棒了!非常感谢,不知道我是怎么错过其他答案的。 【参考方案1】:今天刚遇到这个问题。出于某种原因,您必须设置自定义缩略图,并且它可以工作。
[self.yourSlider setThumbImage:[UIImage imageNamed:@"customThumb"] forState:UIControlStateNormal];
【讨论】:
【参考方案2】:同时在 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)
【讨论】:
以上是关于iOS - UISlider 在第一次触摸时跳跃的主要内容,如果未能解决你的问题,请参考以下文章