Draw a semi-circle button iOS
Asked Answered
N

3

7

I am trying to draw a semi-circle button. I'm having trouble both drawing the semi-circle and attaching it to the button I made in xcode. The button in xcode has constraints pinning it to the bottom of the screen and centering it. I reference the button in my view controller and then try to override it to a semi-circle as follows. I am getting a blank button. I also hard coded in the coordinates from the storyboard of where the button is. Is there a better way to do that?

let circlePath = UIBezierPath.init(arcCenter: CGPoint(x: 113.0, y: 434.0),
radius: 10.0, startAngle: 0.0, endAngle: CGFloat(M_PI), clockwise: true)

let circleShape = CAShapeLayer()
circleShape.path = circlePath.CGPath

sunButton.layer.mask = circleShape
Null answered 23/10, 2015 at 18:19 Comment(1)
To clarify, this is within a function that I am calling on viewDidLoad and the reference to my button is sunButton!Null
A
14

The problem is that your shape layer is positioned way outside the buttons bounds. If you just add the shape layer as a subview of your button's layer you'll see the problem:

button.layer.addSublayer(circleShape)

enter image description here

You have to adjust the arc center point, so that the arc lies within the button's bounds:

let circlePath = UIBezierPath.init(arcCenter: CGPointMake(button.bounds.size.width / 2, 0), radius: button.bounds.size.height, startAngle: 0.0, endAngle: CGFloat(M_PI), clockwise: true)
let circleShape = CAShapeLayer()
circleShape.path = circlePath.CGPath
button.layer.mask = circleShape

And you'll get this:

enter image description here

Adahadaha answered 23/10, 2015 at 19:32 Comment(7)
It was very helpful for me but I got an issue. The button is also click able outside the coloured area(actual area of button) how can I disable this functionality ?Snead
Hi @UmairAfzal. In your UIButton subclass you can override hitTest(_:withEvent:) to define which area of your button is clickable. Have a look at this tutorial for details: planet1107.net/blog/custom-shape-uibutton-tutorialAdahadaha
@Adahadaha Hi if i want the reverse of this arc,what i have to do?Telephoto
@Elan Set clockwise to falseAdahadaha
@Adahadaha if i do like this my view is not visible to me,code i have used is as follows:- ' [path addArcWithCenter:CGPointMake(size.width / 2.0, 0) radius:self.bounds.size.height startAngle:0 endAngle:M_PI clockwise:false]; CAShapeLayer *shapeView = [[CAShapeLayer alloc] init]; shapeView.fillColor=[UIColor greenColor].CGColor; shapeView.path=[path CGPath]; self.layer.mask=shapeView; 'Telephoto
You have to set the arc's center y to size.height instead of 0. Because the circle is drawn from the bottom to the top now.Adahadaha
I want to set to reverse can you please help me. I want code in swift. ThanksTrumpeter
B
3

Swift 5 update:

let circlePath = UIBezierPath.init(arcCenter: CGPoint(x: button.bounds.size.width / 2, y: 0), radius: button.bounds.size.height, startAngle: 0.0, endAngle: .pi, clockwise: true)
let circleShape = CAShapeLayer()
circleShape.path = circlePath.cgPath
button.layer.mask = circleShape
Boulder answered 21/7, 2019 at 19:22 Comment(0)
C
3

Swift 5:

    // semiCircleDown
  let circlePath =  UIBezierPath(arcCenter: CGPoint(x: shapeView.bounds.size.width/2, y: 0), radius: shapeView.bounds.size.height, startAngle: 0, endAngle: .pi, clockwise: true).cgPath

        //semiCircleUp
  let circlePath =  UIBezierPath(arcCenter: CGPoint(x: shapeView.bounds.size.width/2, y: 0), radius: shapeView.bounds.size.height, startAngle: 2 * .pi, endAngle: .pi, clockwise: true).cgPath

        //quarterCircleRightDown
  let circlePath =  UIBezierPath(arcCenter: CGPoint(x: 0, y: 0), radius: shapeView.bounds.size.width, startAngle: 2 * .pi, endAngle: .pi * 3/2, clockwise: true).cgPath

        //quarterCircleLeftDown 
  let circlePath =  UIBezierPath(arcCenter: CGPoint(x: shapeView.bounds.size.width, y: 0), radius: shapeView.bounds.size.width, startAngle: .pi * 3/2, endAngle: .pi, clockwise: true).cgPath

        quarterCircleRightUp
  let circlePath = UIBezierPath(arcCenter: CGPoint(x: 0, y: shapeView.bounds.size.height), radius: shapeView.bounds.size.width, startAngle: 0, endAngle: .pi/2, clockwise: false).cgPath

        //quarterCircleLeftUp
  let circlePath = UIBezierPath(arcCenter: CGPoint(x: shapeView.bounds.size.width, y: shapeView.bounds.size.height), radius: shapeView.bounds.size.width, startAngle: .pi/2, endAngle: .pi, clockwise: false).cgPath

let shape = CAShapeLayer()
shape.path = circlePath.cgPath
shapeView.layer.mask = shape
Crusted answered 8/9, 2020 at 2:3 Comment(1)
What is circleShape?Trumpeter

© 2022 - 2024 — McMap. All rights reserved.