在iOS上使用swift绘制视图后,以编程方式绘制新图层

时间:2018-05-07 19:09:54

标签: ios swift

我需要在滑块上的任意点上绘制一个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之后立即拨打layoutIfNeededself.view以及self.slider.superview,但是这些电话会在似乎没有任何影响。 : - /

如何以编程方式将这些新图层绘制到我的writeTickMarks

2 个答案:

答案 0 :(得分:2)

免责声明 - 当我从viewDidLayoutSubviews调用您的方法时,我无法回答为什么根本不显示刻度线,这很奇怪。但是......

我遇到了许多相同概念的头痛 - 视图控制器生命周期以及它何时实际理解视图的真实几何。 viewDidLayoutSubviews的问题在于,当加载UI时,它经常被多次调用,这会导致CALayers被多次添加。

我还有一个CAShapeLayerUIBezierPath一起使用。我有一个适合我的hacky解决方案。

  1. 我确实在CAShapeLayer中调用了viewDidLayoutSubviews init方法(相当于您的writeTickMarks()方法)。
  2. 我将CAShapeLayer作为类级属性,并检查每个方法调用是否为非零:

    if self.shapeLayer != nil {
        self.shapeLayer!.removeFromSuperView()
        self.shapeLayer = nil
    }
    

    我删除并取消分配它,如果它是非零的,以避免在viewDidLayoutSubviews的每次调用时添加它。

  3. 效率不高,但可以绕过viewDidLayoutSubviewsviewDidLoad中未知几何体的多次调用。

答案 1 :(得分:1)

代码应该按原样运行(并且没有setNeedsDisplay / layoutIfNeeded调用)。检查以确保您不仅仅是在屏幕上画画。我自己做了类似的事情,我的计算y值将我的点数设置在屏幕下边缘以下900px。