irkinosor
irkinosor

Reputation: 776

Drawing circles proportionally to containing view in swift

I am trying to draw 3 circles inside my 3 views but only the top view circle is drawn even doth the code is the same. I can't seem to understand where is the problem, that's why the two other circle are not there?

class ViewController: UIViewController {  

  ///Views used to display the progress view
  var topView: CircleView!
  var middleView: CircleView!
  var bottomView: CircleView!  

  override func viewDidLoad() {
    super.viewDidLoad()
    createThreeViews()
  }

  func createThreeViews(){        
    let viewHeight = self.view.bounds.height
    let viewWidth = self.view.bounds.width

    //Top View 
    let topTimerFrame = CGRect(x: 0, y: 0, width: viewWidth, height: 3/6 * viewHeight)
    topView = CircleView(frame: topTimerFrame)
    topView.backgroundColor = UIColor.redColor()

    //Middle View
    let middleTimerFrame = CGRect(x: 0, y: topTimerFrame.height, width: viewWidth, height: 2/6 * viewHeight)

    middleView = CircleView(frame: middleTimerFrame)
    middleView.backgroundColor = UIColor.blueColor()


    //Bottom view
    let bottomTimerFrame = CGRect(x: 0, y: topTimerFrame.height + middleTimerFrame.height, width: viewWidth, height: 1/6 * viewHeight)

    bottomView = CircleView(frame: bottomTimerFrame)
    bottomView.backgroundColor = UIColor.greenColor()

    //add top circle and set constraint
    self.view.addSubview(topView)

    //add middle circle and set constraints
    self.view.addSubview(middleView)

    //add bottom circle and set constraints
    self.view.addSubview(bottomView)
  }

}

//class used to create the views and draw circles in them
class CircleView: UIView {
  let π:CGFloat = CGFloat(M_PI)    
  let circle = CAShapeLayer()    
  var secondLayerColor: UIColor = UIColor.whiteColor()


  //custom initializer
  override init(frame: CGRect) {
    super.init(frame: frame)
    userInteractionEnabled = true
    setup()
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    userInteractionEnabled = true
    setup()
  }

  func setup() {

    //draw the circle and add to layer
    circle.frame = bounds
    circle.lineWidth = CGFloat(4)
    circle.fillColor = UIColor.whiteColor().CGColor
    circle.strokeEnd = 1

    layer.addSublayer(circle)
    setupShapeLayer(circle)
  }

  override func layoutSubviews() {        
    super.layoutSubviews()
    setupShapeLayer(circle)       
  }

  func setupShapeLayer(shapeLayer: CAShapeLayer) {        
    shapeLayer.frame = bounds        
    let radius = frame.height/2 - circle.lineWidth/2        
    let startAngle = CGFloat(0)        
    let endAngle = 2*π        
    let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)        
    shapeLayer.path = path.CGPath        
  }

}

wrong result I am getting

Upvotes: 1

Views: 1033

Answers (1)

Daniel Klöck
Daniel Klöck

Reputation: 21137

You are drawing your circle with an offset to your frame (the other two circles are drawn, but outside of the frames).

Change:

let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)

to:

let path = UIBezierPath(arcCenter: CGPoint(x: center.x , y: frame.height/2) , radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)

Btw. you probably want to change setupShapeLayer(circle) in setup() to setNeedsLayout(); layoutIfNeeded(), otherwise it will be drawn twice the first time.

Upvotes: 1

Related Questions