UISlider 的拇指中心位于轨道的起点和终点 [英] UISlider with thumb center over the start and end of track

查看:22
本文介绍了UISlider 的拇指中心位于轨道的起点和终点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UISlider 的默认行为是它的拇指不在轨道的开始/结束处居中.如下图:

The default behaviour of UISlider is that its thumb isn't centered on start/end of track. Like below:

我想修改它的行为以获得:

I would like to modify it's behaviour to get:

拇指的中心可以定位在开始或结束的位置.

where thumb's center can be positioned on start or end.

我试图用空的 UIView 覆盖开始/结束.效果是看起来几乎没问题,但拇指有阴影显示我在某些位置的 hack(我可以忍受),但是我的 hacky 视图覆盖了一点拇指并捕获了它的触摸事件(甚至当用户交互被禁用时).

I have tried to cover start/end with empty UIView. Effect is that is look almost ok, but thumb has dropshadow that reveals my hack in some positions (which I can live with), however my hacky view covers a little the thumb and captures it's touch event (even when user interactions are disabled).

所以我想我需要在拇指和轨道之间打包我的hacky视图.可能无需操纵其内部视图.有什么想法吗?

So I guess I would need to pack my hacky view between thumb and track. Possibly without manipulating its internal views. Any ideas?

推荐答案

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

UISlider class has a method thumbRect(forBounds:trackRect:value:) that you can override to control the drawing rectangle for the slider’s thumb image. So assuming that this space is 5 points (might vary depending on the thumb image you are using) we can do the following:

  1. 子类 UISlider 并覆盖 thumbRect(forBounds:trackRect:value:) 以将我们自己挂钩到流程中
  2. 定义thumbSpace(我假设它是5),我们可以根据thumbSpace 计算起始偏移量(滑块前5 个点)和结束偏移量(滑块后5 个点).
  3. 计算与当前值、minValue 和 maxValue 相关的拇指平移(换句话说,根据当前值,我们稍微移动拇指以覆盖我们不想显示的空间)
  4. 将一个移动的矩形(在应用 x 平移后)返回给 super 方法以进行常规计算
  1. Subclass UISlider and override thumbRect(forBounds:trackRect:value:) to hook ourselves into the process
  2. Define the thumbSpace (I assumed it is 5), and from the thumbSpace we can calculate starting offset (5 points before the slider) and ending offset (5 points after the slider).
  3. Calculate the thumb translation in relation to current value, minValue and maxValue (In other words, based on the current value, we are shifting the thumb a little to cover the spaces we don't want to show)
  4. Return a shifted rectangle (after applying the x translation) to the super method to do the regular calculations

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

The complete code should be like the following:

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)
    }
}

这篇关于UISlider 的拇指中心位于轨道的起点和终点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆