我们正在尝试为以下场景找到仅限故事板的解决方案:
我们希望设置"里程碑" /"步骤" UISlider上方的标签。值为0.2的拇指位置应恰好位于其上方对应标签的中间。标签位置将适应的重要性取决于屏幕,因此约束需要与比例成正比。插图:
我们尝试了什么:
我们将UIStackView放置在滑块上方的7个排列的子视图(每个步骤一个),并使其稍微宽一些(滑块宽度的1.14倍,其目的是大1/7)。出于某种原因,它对齐某些步骤而不与其他步骤对齐。样品:
任何有关解决问题的建议或建议都将受到高度赞赏。谢谢!
最诚挚的问候,Roi
答案 0 :(得分:1)
Complete Playground source available here
如果您继承UISlider
,则可以覆盖thumbRect(forBounds:trackRect:value:)
方法,该方法允许您调整显示拇指图像的矩形。这样做,并使其成为拇指 - 图像的中心位于轨道上的相应点上。
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
let superThumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
let valueAsDecimalFraction = value == minimumValue ? 0 : (value - minimumValue)/(maximumValue - minimumValue)
let valueAsDecimalFractionOfMinusOneToOne = (valueAsDecimalFraction*2 - 1)/2
let xOffset = CGFloat(valueAsDecimalFractionOfMinusOneToOne) * superThumbRect.width
return CGRect(
x: superThumbRect.origin.x + xOffset,
y: superThumbRect.origin.y,
width: superThumbRect.size.width,
height: superThumbRect.size.height)
}
一旦覆盖thumbRect(forBounds:trackRect:value:)
,您将看到拇指图像现在具有正确的行为,除非它现在在滑块处于最小值或最大值时挂在视图外。要更正此问题,请覆盖trackRect(forBounds:)
方法,以便使用允许拇指图像保留在滑块边界内的某个值填充轨道。
let padding = CGFloat(18)
override func trackRect(forBounds bounds: CGRect) -> CGRect {
let superTrackRect = super.trackRect(forBounds: bounds)
return CGRect(
x: superTrackRect.origin.x + padding,
y: superTrackRect.origin.y,
width: superTrackRect.size.width - padding*2,
height: superTrackRect.size.height)
}
您可能很难使用UILabel
定位UIStackView
- 标签的中心点将不在正确的位置。相反,使用相对于滑块的约束来布局标签。
// Assuming labels: [UILabel], and a value of thumbIndent
override func viewWillLayoutSubviews() {
let labelConstraints = labels.enumerated().map { (i, label) -> [NSLayoutConstraint] in
let pct = CGFloat(i)/CGFloat(labels.count-1)
let centerX = (view.bounds.size.width-2*thumbIndent) * pct + thumbIndent
return [
label.centerXAnchor.constraint(equalTo: slider.leftAnchor, constant: centerX),
label.bottomAnchor.constraint(equalTo: slider.topAnchor, constant: 0),
]
}.flatMap { $0 }
.
.
.
}