title: How to rotate a CGRect about its centre?
body: <p>Background:</p>
  
  <p>I want to show a label that is rotated 90 degrees clockwise. The rotated label should be in a certain frame that I specify. Let's say (10, 100, 50, 100).</p>
  
  <p>I know that I can rotate a view by using <code>CGAffineTransform</code>. I also know that I should not set the <code>frame</code> property after a transformation is done, according to the <a href="https://developer.apple.com/documentation/uikit/uiview/1622459-transform" rel="nofollow noreferrer">docs</a>.</p>
  
  <blockquote>
    <p>When the value of this property is anything other than the identity transform, the value in the frame property is undefined and should be ignored.</p>
  </blockquote>
  
  <p>I tried to set the frame after the transform and although it worked, I don't want to do something that the docs told me not to.</p>
  
  <pre><code>label2.transform = CGAffineTransform(rotationAngle: -.pi / 2)
  label2.frame =  CGRect(x: 10, y: 100, width: 50, height: 100)
  </code></pre>
  
  <hr>
  
  <p>Then I thought, I could do this:</p>
  
  <ol>
  <li>create a <code>CGRect</code> of the frame that I want</li>
  <li>rotate that rect 90 degrees anticlockwise</li>
  <li>set that rect as the frame of the label</li>
  <li>rotate the label 90 degrees clockwise</li>
  </ol>
  
  <p>And then the label would be in the desired frame.</p>
  
  <p>So I tried something like this:</p>
  
  <pre><code>    let desiredFrame = CGRect(x: 10, y: 100, width: 50, height: 100) // step 1
      // I am using UIViews here because I am just looking at their frames
      // whether it is a UIView or UILabel does not matter
      // label1 is a view that is in the desired frame but not rotated
      // If label2 has the correct frame, it should completely cover label1
      let label1 = UIView(frame: desiredFrame)
      let label2Frame = rotateRect(label1.frame) // step 2
      let label2 = UIView(frame: label2Frame) // step 3
      view.addSubview(label1)
      view.addSubview(label2)
      label1.backgroundColor = .red
      label2.backgroundColor = .blue
      label2.transform = CGAffineTransform(rotationAngle: -.pi / 2) // step 4
  </code></pre>
  
  <p>Where <code>rotateRect</code> is declared like this:</p>
  
  <pre><code>func rotateRect(_ rect: CGRect) -&gt; CGRect {
      return rect.applying(CGAffineTransform(rotationAngle: .pi / 2))
  }
  </code></pre>
  
  <p>This didn't work. <code>label2</code> does not overlap <code>label1</code> at all. I can't even see <code>label2</code> at all on the screen.</p>
  
  <p>I suspect that this is because the <code>applying</code> method in <code>CGRect</code> rotates the rect about the origin, instead of the centre of the rect. So I tried to first transform the rect to the origin, rotate it, then transform it back, as this <a href="https://math.stackexchange.com/questions/2581058/rotating-rectangle-by-its-center">post</a> on math.SE said:</p>
  
  <pre><code>func rotateRect(_ rect: CGRect) -&gt; CGRect {
      let x = rect.x
      let y = rect.y
      let transform = CGAffineTransform(translationX: -x, y: -y)
                          .rotated(by: .pi / 2)
                          .translatedBy(x: x, y: y)
      return rect.applying(transform)
  }
  </code></pre>
  
  <p>However, I still cannot see <code>label2</code> on the screen.</p>