UISlider 的拇指中心位于轨道的起点和终点 [英] UISlider with thumb center over the start and end of track
问题描述
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:
- 子类
UISlider
并覆盖thumbRect(forBounds:trackRect:value:)
以将我们自己挂钩到流程中 - 定义thumbSpace(我假设它是5),我们可以根据thumbSpace 计算起始偏移量(滑块前5 个点)和结束偏移量(滑块后5 个点).
- 计算与当前值、minValue 和 maxValue 相关的拇指平移(换句话说,根据当前值,我们稍微移动拇指以覆盖我们不想显示的空间)
- 将一个移动的矩形(在应用 x 平移后)返回给 super 方法以进行常规计算
- Subclass
UISlider
and overridethumbRect(forBounds:trackRect:value:)
to hook ourselves into the process - 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).
- 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)
- 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屋!