title: Zoom a rotated image inside scroll view to fit (fill) frame of overlay rect
body: <p>Through <a href="https://stackoverflow.com/questions/26821725/determine-if-crop-rect-is-entirely-contained-within-rotated-uiview?lq=1#26822021">this question and answer</a> I've now got a working means of detecting when an arbitrarily rotated image isn't completely outside a cropping rect.</p>
  
  <p>The next step is to figure out how to correctly adjust it's containing scroll view zoom to ensure that there are no empty spaces inside the cropping rect. To clarify, I want to enlarge (zoom in) the image; the crop rect should remain un-transformed.</p>
  
  <p>The layout hierarchy looks like this:</p>
  
  <pre><code>containing UIScrollView
      UIImageView (this gets arbitrarily rotated)
          crop rect overlay view
  </code></pre>
  
  <p>... where the UIImageView can also be zoomed and panned inside the scrollView.</p>
  
  <p>There are 4 gesture events that occur that need to be accounted for:</p>
  
  <ol>
  <li>Pan gesture (done): accomplished by detecting if it's been panned incorrectly and resets the contentOffset.</li>
  <li>Rotation CGAffineTransform</li>
  <li>Scroll view zoom</li>
  <li>Adjustment of the cropping rect overlay frame</li>
  </ol>
  
  <p>As far as I can tell, I should be able to use the same logic for 2, 3, and 4 to adjust the zoomScale of the scroll view to make the image fit properly.</p>
  
  <p><strong>How do I properly calculate the zoom ratio necessary to make the rotated image fit perfectly inside the crop rect?</strong></p>
  
  <p>To better illustrate what I'm trying to accomplish, here's an example of the incorrect size:</p>
  
  <p><img src="https://i.stack.imgur.com/eqYar.png" alt="enter image description here"></p>
  
  <p>I need to calculate the zoom ratio necessary to make it look like this:</p>
  
  <p><img src="https://i.stack.imgur.com/8dhMA.png" alt="enter image description here"></p>
  
  <p>Here's the code I've got so far using Oluseyi's solution below. It works when the rotation angle is minor (e.g. less than 1 radian), but anything over that and it goes really wonky.</p>
  
  <pre><code>CGRect visibleRect = [_scrollView convertRect:_scrollView.bounds toView:_imageView];
  CGRect cropRect = _cropRectView.frame;
  
  CGFloat rotationAngle = fabs(self.rotationAngle);
  
  CGFloat a = visibleRect.size.height * sinf(rotationAngle);
  CGFloat b = visibleRect.size.width * cosf(rotationAngle);
  CGFloat c = visibleRect.size.height * cosf(rotationAngle);
  CGFloat d = visibleRect.size.width * sinf(rotationAngle);
  
  CGFloat zoomDiff = MAX(cropRect.size.width / (a + b), cropRect.size.height / (c + d));
  CGFloat newZoomScale = (zoomDiff &gt; 1) ? zoomDiff : 1.0 / zoomDiff;
  
  [UIView animateWithDuration:0.2
                        delay:0.05
                      options:NO
                   animations:^{
                           [self centerToCropRect:[self convertRect:cropRect toView:self.zoomingView]];
                           _scrollView.zoomScale = _scrollView.zoomScale * newZoomScale;
                   } completion:^(BOOL finished) {
                       if (![self rotatedView:_imageView containsViewCompletely:_cropRectView]) 
                       {
                           // Damn, it's still broken - this happens a lot
                       }
                       else
                       {
                           // Woo! Fixed
                       }
                       _didDetectBadRotation = NO;
                   }];
  </code></pre>
  
  <p>Note I'm using AutoLayout which makes frames and bounds goofy.</p>