我需要在滑块上的任意点上绘制一个UISlider
。
我可以在viewDidLoad
中绘制刻度线,但由于此时我无法获得UISlider
的正确范围,因此它们会被吸引到错误的地方。如果我在viewDidLayoutSubviews
中绘制它们,我会得到正确的界限,但刻度标记不会显示。
我试图按如下方式绘制这些标记:
override func viewDidLayoutSubviews(){
super.viewDidLayoutSubviews()
writeTickMarks()
}
func writeTickMarks(){
// create a vertical line
let path = UIBezierPath()
path.move(to: CGPoint(x: calculatedXValue, y: calculatedYValue))
path.addLine(to: CGPoint(x: calculatedXValue, y: calculatedYValue + 5))
// draw the vertical line in blue with a thickness of 2
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.opacity = 0.5
shapeLayer.lineWidth = 2
// add the shape to the slider's view
self.slider.superview?.layer.addSublayer(shapeLayer)
}
我已经尝试在setNeedsDisplay
之后立即拨打layoutIfNeeded
和self.view
以及self.slider.superview
,但是这些电话会在似乎没有任何影响。 : - /
如何以编程方式将这些新图层绘制到我的writeTickMarks
?
答案 0 :(得分:2)
免责声明 - 当我从viewDidLayoutSubviews
调用您的方法时,我无法回答为什么根本不显示刻度线,这很奇怪。但是......
我遇到了许多相同概念的头痛 - 视图控制器生命周期以及它何时实际理解视图的真实几何。 viewDidLayoutSubviews
的问题在于,当加载UI时,它经常被多次调用,这会导致CALayers被多次添加。
我还有一个CAShapeLayer
与UIBezierPath
一起使用。我有一个适合我的hacky解决方案。
CAShapeLayer
中调用了viewDidLayoutSubviews
init方法(相当于您的writeTickMarks()
方法)。我将CAShapeLayer
作为类级属性,并检查每个方法调用是否为非零:
if self.shapeLayer != nil {
self.shapeLayer!.removeFromSuperView()
self.shapeLayer = nil
}
我删除并取消分配它,如果它是非零的,以避免在viewDidLayoutSubviews
的每次调用时添加它。
效率不高,但可以绕过viewDidLayoutSubviews
和viewDidLoad
中未知几何体的多次调用。
答案 1 :(得分:1)
代码应该按原样运行(并且没有setNeedsDisplay / layoutIfNeeded调用)。检查以确保您不仅仅是在屏幕上画画。我自己做了类似的事情,我的计算y值将我的点数设置在屏幕下边缘以下900px。