title: Wrong position of CAShapelayer in sublayers of UIView
body: <p>I'm trying to draw: O-O-O in the midY of UIView but get:</p>
  
  <p><a href="https://i.stack.imgur.com/miLSr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/miLSr.png" alt="wrong position of layers"></a></p>
  
  <p>Here is a func for calculating position for CAShapeLayer.frame. Even indices are dots and odd indices are lines. Number of lines is always minus one number of dots.</p>
  
  <pre><code>func frameForShape(at index: Int) -&gt; CGRect {
      let dotWidth = dotRadius * 2
      let lineWidth = (view.bounds.width - (CGFloat(numberOfDots) * dotWidth)) / CGFloat(numberOfLines)
  
      if index % 2 == 0 {
          let count = CGFloat(index) / 2
          let x = (lineWidth * count) + (dotWidth * count)
          return CGRect(x: x, y: 0, width: dotWidth, height: view.bounds.height)
      } else {
          let count = Double(index) / 2
          let x = (lineWidth * CGFloat(floor(count))) + (dotWidth * CGFloat(ceil(count)))
          return CGRect(x: x, y: 0, width: lineWidth, height: view.bounds.height)
      }
  }
  
  func setFrame() {
      for (index, shape) in shapes.enumerated() {
          shape.frame = frameForShape(at: index)
      }
  }
  </code></pre>
  
  <p>frameForShape(at:) correctly return frame position and size</p>
  
  <p><a href="https://i.stack.imgur.com/DVtQ0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DVtQ0.png" alt="results of frameForShape(at:)"></a></p>
  
  <p>This funcs draw a path in the center of given frame </p>
  
  <pre><code>func linePath(rect: CGRect) -&gt; UIBezierPath {
      let newRect = CGRect(x: rect.minX, y: rect.midY - (lineHeight / 2), width: rect.width, height: lineHeight)
      let path = UIBezierPath(rect: newRect)
      return path
  }
  
  func dotPath(rect: CGRect) -&gt; UIBezierPath {
      let newRect = CGRect(x: rect.midX - dotRadius, y: rect.midY - dotRadius, width: dotRadius * 2, height: dotRadius * 2)
      let path = UIBezierPath(ovalIn: newRect)
      return path
  }
  </code></pre>
  
  <p>Here, I'm adding CAShapeLayers to yellow UIView</p>
  
  <pre><code>override func awakeFromNib() {
      super.awakeFromNib()
  
      for shape in shapes {
          view.layer.addSublayer(shape)
      }
  }
  
  override func layoutSubviews() {
      super.layoutSubviews()
      layoutIfNeeded()
  
      setFrame()
      build()
  }
  
  func build() {
      for (index, shape) in shapes.enumerated() {
          if index % 2 == 0 {
              shape.path = dotPath(rect: shape.frame).cgPath
          } else {
              shape.path = linePath(rect: shape.frame).cgPath
          }
      }
  }
  </code></pre>
  
  <p>Frames are correct so why dots and lines are misplaced?</p>
  
  <p>I found this answer: <a href="https://stackoverflow.com/a/40194019/">https://stackoverflow.com/a/40194019/</a></p>
  
  <blockquote>
    <p>incorrect position of your layer - frame should be equal to bounds of parent layer in parentView</p>
  </blockquote>
  
  <p>But how draw path at specific position if UIBezierPath(ovalIn:) and UIBezierPath(rect:) draw all inside frame?</p>