UISlider,拇指中心位于音轨的开始和结束位置

Fis*_*man 5 uikit uislider ios

的默认行为UISlider是它的拇指不在轨道的开始/结束的中心。如下所示:

默认的UISlider

我想将其行为修改为:

所需的滑块

拇指中心可以位于起点或终点的位置。

我试图用empty覆盖开始/结束UIView。效果是看起来几乎可以,但是拇指具有阴影,可以在某些位置显示我的hack(我可以忍受),但是我的hacky视图覆盖了一点拇指并捕获了触摸事件(即使禁用了用户交互)。

所以我想我需要将我的hacky视图放在拇指和铁轨之间。可能无需操纵其内部视图。有任何想法吗?

Mos*_*eef 9

UISlider 类有一个方法thumbRect(forBounds:trackRect:value:)你可以重写它来控制滑块的拇指图像的绘制矩形。因此,假设此空间为 5 点(可能因您使用的拇指图像而异),我们可以执行以下操作:

  1. 子类化UISlider和覆盖thumbRect(forBounds:trackRect:value:)以将我们自己挂钩到流程中
  2. 定义thumbSpace(我假设它是5),从thumbSpace我们可以计算出起始偏移量(滑块前5点)和结束偏移量(滑块后5点)。
  3. 计算与当前值、minValue 和 maxValue 相关的拇指平移(换句话说,基于当前值,我们稍微移动拇指以覆盖我们不想显示的空间)
  4. 将一个移位的矩形(在应用 x 平移后)返回给 super 方法以进行常规计算

完整的代码应该如下所示:

class CustomSlider: UISlider {
    let defaultThumbSpace: Float = 5
    lazy var startingOffset: Float = 0 - defaultThumbSpace
    lazy var endingOffset: Float = 2 * defaultThumbSpace

    override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
        let xTranslation =  startingOffset + (minimumValue + endingOffset) / maximumValue * value
        return super.thumbRect(forBounds: bounds,
                               trackRect: rect.applying(CGAffineTransform(translationX: CGFloat(xTranslation),
                                                                          y: 0)),
                               value: value)
    }
}
Run Code Online (Sandbox Code Playgroud)


erg*_*cak 5

Swift 5 版本适合像我这样的懒人:)

class CustomSlider: UISlider {

    private let trackHeight: CGFloat = 8

    override func trackRect(forBounds bounds: CGRect) -> CGRect {
        let point = CGPoint(x: bounds.minX, y: bounds.midY)
        return CGRect(origin: point, size: CGSize(width: bounds.width, height: trackHeight))
    }

    private let thumbWidth: Float = 52
    lazy var startingOffset: Float = 0 - (thumbWidth / 2)
    lazy var endingOffset: Float = thumbWidth

    override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
        let xTranslation =  startingOffset + (minimumValue + endingOffset) / maximumValue * value
        return super.thumbRect(forBounds: bounds, trackRect: rect.applying(CGAffineTransform(translationX: CGFloat(xTranslation), y: 0)), value: value)
    }
}
Run Code Online (Sandbox Code Playgroud)