首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >iOS - UISlider在第一次触摸时跳转

iOS - UISlider在第一次触摸时跳转
EN

Stack Overflow用户
提问于 2014-04-06 03:27:29
回答 2查看 2.5K关注 0票数 19

我在使用Xcode5.1开发的iOS应用程序中添加了一个UISlider,并且我无法摆脱以下恼人的行为。当我第一次触摸拇指时,它会稍微跳动一下。

这里有一个快速示例,详细说明了该行为。

当滑块拇指最初定位在中心的左侧(例如,在最小值处)时,它会跳到右侧。如果我在iOS模拟器中运行应用程序,拇指在第一次触摸时不需要任何拖动就会跳转。拇指总是跳向赛道的中心。唯一一次它不会跳跃是当它在轨道的精确中心时。即使滑块未连接到任何对象,也会显示此行为。

有什么办法可以禁用它吗?

EN

回答 2

Stack Overflow用户

发布于 2015-06-30 07:10:38

今天偶然发现了这个问题。由于某些原因,你必须设置一个自定义的拇指图像,它可以工作。

代码语言:javascript
复制
[self.yourSlider setThumbImage:[UIImage imageNamed:@"customThumb"] forState:UIControlStateNormal];
票数 4
EN

Stack Overflow用户

发布于 2019-08-30 17:29:53

同时,2019年的和iOS 12也有那个bug

这是一个老问题,也是一个相关的问题。因此,虽然公认的答案工作正常,但它有一个小而重要的问题-拇指触摸区域变得越来越小,而在大多数情况下,增加可触摸区域会导致新的跳转(我尝试过覆盖thumbRect(forBounds和beginTracking方法))

让我们来解决它吧!

所以解决方案不是很复杂,但有点不方便(需要一些图像资源),仍然比重新实现自己的Slider更容易

这个类的目的是为了消除在点击时跳动拇指的UIKit错误。主要的技巧是用一些图像替换原来的拇指,其他代码是扩展点击区域,这是: 1)设置一个图像与一些边阿尔法偏移,即一个圆圈,其中较大的矩形

setThumbImage(thumb,用于:.normal)

2)更大的图像意味着更大的拇指,因此最小和最大值上的轨迹在图像的alpha区域下可见。因此下一步是分别在左侧和右侧设置最小和最大轨迹图像,

setMinimumTrackImage(anImage,用于:.normal) setMaximumTrackImage(maxSliderImage,用于:.normal)

但是图像也有一个alpha区域,需要用来“隐藏”拇指两侧的轨迹(最小/最大值在它完全可见的地方)。

4)虽然我们有更大的拇指和轨迹视觉上减少(分别到滑块边界宽度),但需要通过覆盖trackRect(forBounds方法)来增加轨迹的可见部分。我们将不会有超出滑块边界的轨迹作为最小/最大图像的一部分是透明的5)因为目标之一是增加拇指的触摸区需要重写point(inside point:,with event:)方法来在两侧创建可触摸区

PS:别忘了在xcassets中设置最小和最大滑块轨迹属性: 1)水平切片和左/右插入2)条纹技术

代码语言:javascript
复制
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)
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22885695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档