【问题标题】:iOS - UISlider jumps on first touchiOS - UISlider 在第一次触摸时跳跃
【发布时间】:2014-04-05 19:27:29
【问题描述】:

我已将UISlider 添加到我正在使用 Xcode 5.1 开发的 iOS 应用程序中,但我无法摆脱以下烦人的行为。当我第一次触摸拇指时,它会轻微跳跃。

这是一个详细说明行为的快速示例。

当滑块最初位于中心的左侧时(例如,在最小值处),它会跳到右侧。如果我在 iOS 模拟器中运行该应用程序,拇指在第一次触摸时会跳动而没有任何拖动。拇指总是跳向轨道的中心。它唯一不跳跃的时候是它在轨道的精确中心。即使滑块未连接到任何东西,也会出现此行为。

有什么办法可以禁用它?

【问题讨论】:

  • @ipinak 很明显。不需要代码。
  • 这纯粹是模拟器现象吗?你有一个方便的设备可以试一试吗?如果它只是一个模拟器的东西,你应该笑着忽略它。鼠标光标不是大胖手指,可能是模拟器在做某种补偿。
  • 不,当我在 iPad 上测试时也会发生这种情况。我刚才提到模拟器是为了强调“跳跃”不是我无意中在 ipad 屏幕上移动手指的结果。
  • 好的,这个是已知的,有解决办法:stackoverflow.com/questions/20903317/…
  • 太棒了!非常感谢,不知道我是怎么错过其他答案的。

标签: ios uislider


【解决方案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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2012-10-06
      • 2020-11-06
      相关资源
      最近更新 更多