自定义滑块和自动布局问题



我有一个带有xib的UIView子类,我正在尝试将其放入带有离散点的滑块中。

我有一个"轨道"和一个"拇指"。沿着轨道,我希望有 4 个均匀间隔的圆圈,拇指在拖动时可以捕捉到它们。

我使用的代码如下:

override func awakeFromNib() {
    // Layout circles
    for index in stride(from: numberOfCircles, to: 0, by: -1) {
        let xValue = (((index - 1)/(numberOfCircles - 1))*track.frame.size.width) - circleSize/2 + thumbWidth.constant/2
        makeCircle(withXValue: xValue)
    }
}
fileprivate func makeCircle(withXValue xValue: CGFloat) {
    let circle = CAShapeLayer()
    circle.path = UIBezierPath(ovalIn: CGRect(x: xValue , y: self.frame.height/2 - circleSize/2, width: circleSize, height: circleSize)).cgPath
    circle.fillColor = UIColor(red: 238/255, green: 79/255, blue: 84/255, alpha: 1).cgColor
    self.layer.addSublayer(circle)
}

我认为这会起作用,但是,track.frame.size.width不正确。这是因为我将这个UIView子类添加到另一个视图中,并使用自动布局来设置其宽度。它以 awakeFromNib() 为单位返回的宽度只是它在 xib 中的值。如何获取轨道的实际自动布局宽度来解决此问题?

使路径独立于位置

circle.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: circleSize, height: circleSize)).cgPath

代替这个position使用CALayer类的属性:

circle.position = CGPoint(x: xValue , y: self.frame.height/2 - circleSize/2)

将圆形图层保存在属性中,以便在框架更改时可以访问它们。让图层的创建方法返回它创建的图层makeCircle(withXValue xValue: CGFloat) -> CAShapeLayer。并将其保存在awakeFromNib()circles.append(makeCircle(withXValue: calculateXValueForCircle(atIndex: index))

当视图框架更改时,将调用方法 layoutSublayers。重写方法layoutSublayers(of layer: CALayer)以使用新帧值设置位置:

    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        if layer == self.layer {
            for (index, circle) in circles.enumerated() {
                let newX = calculatePositionForCircle(atIndex: index)
                let newY = self.frame.height/2 - circleSize/2
                circle.position = CGPoint(x: newX, y: newY)
            }
        }
    }
    // Calculating X position better move in method so you don't dublicate your code
    fileprivate func calculatePositionForCircle(atIndex index: Int) -> CGFloat {
        return (((index - 1)/(numberOfCircles - 1))*track.frame.size.width) - circleSize/2 + thumbWidth.constant/2
    }

最新更新