-1

I am looking to design a circular button that has lines around it 360 degrees as shown in a rough idea picture here. Please have a look and share your ideas on how can this be designed either in Android, iOS, or Xamarin.

Thanks

Eishon
  • 1,274
  • 1
  • 9
  • 17
Jason Roy
  • 43
  • 6
  • 3
    Please read [ask] before posting. – Jason Jul 04 '21 at 15:24
  • For iOS check https://stackoverflow.com/questions/56346091/circle-with-dash-lines-uiview thread. What you have to do is create a CAShapeLayer of the button you want to add the dash lines to, and you can play around with the line properties – Visal Rajapakse Jul 04 '21 at 15:41

1 Answers1

0

The idea in iOS is to subclass UIButton and set its base layer to a shape layer and set the path for that shape layer to be a path where you stroke each of those individual lines and the circle. E.g.

@IBDesignable
public class CircularButton: UIButton {

    @IBInspectable public var lineWidth: CGFloat = 3       { didSet { updateShapeLayer() } }
    @IBInspectable public var lineLength: CGFloat = 10     { didSet { updateShapeLayer() } }
    @IBInspectable public var lineCount: Int = 48          { didSet { updateShapeLayer() } }
    @IBInspectable public var insetDistance: CGFloat = 6   { didSet { updateShapeLayer() } }
    @IBInspectable public var strokeColor: UIColor = .red  { didSet { shapeLayer.strokeColor = strokeColor.cgColor } }

    public override class var layerClass: AnyClass { return CAShapeLayer.self }
    private var shapeLayer: CAShapeLayer { return layer as! CAShapeLayer }

    public override func layoutSubviews() {
        super.layoutSubviews()
        updateShapeLayer()
    }
}

private extension CircularButton {
    func updateShapeLayer() {
        let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let outerRadius = min(rect.width, rect.height) / 2
        let innerRadius = outerRadius - lineLength
        let circleRadius = innerRadius - insetDistance

        let path = UIBezierPath()
        if lineLength > 0 {
            for i in 0 ..< lineCount {
                let angle: CGFloat = .pi * 2 * CGFloat(i) / CGFloat(lineCount)
                path.move(to:    CGPoint(x: center.x + cos(angle) * outerRadius, y: center.y + sin(angle) * outerRadius))
                path.addLine(to: CGPoint(x: center.x + cos(angle) * innerRadius, y: center.y + sin(angle) * innerRadius))
            }

            path.move(to: CGPoint(x: center.x + circleRadius, y: center.y))
        }

        path.addArc(withCenter: center, radius: circleRadius, startAngle: 0, endAngle: .pi * 2, clockwise: true)

        shapeLayer.lineCap = .round
        shapeLayer.lineWidth = lineWidth
        shapeLayer.strokeColor = strokeColor.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.path = path.cgPath
    }
}

If the button is 100 × 100pt, that yields:

enter image description here

Rob
  • 415,655
  • 72
  • 787
  • 1,044