Search code examples
iosobjective-ccore-animation

Apply CGAffineTransform prior to layer being displayed


I'm trying to scale an AVCaptureVideoPreviewLayer so it displays a "zoomed in" preview from the camera; I can make this work using setAffineTransform:CGAffineTransformMakeScale(2.0f, 2.0f), but only once the layer is visible on screen. That is, the scale transform doesn't seem to take effect unless I call it (from within a CATransaction) during a callback like viewDidAppear.

What I'd really like to do is have the scale transform be applied prior to the layer becoming visible--e.g. at the time that I initialize it and add it to the UIView--but all my attempts to do so have proven futile. If I set the transform at this point, and then attempt to read the value back once it is visible, it does appear to have the desired scale transform set -- yet it does not have any effect on the view. I'm new to iOS programming, so I'm sure there's something basic I'm missing here; any help is appreciated!


Solution

  • Two simple alternative approaches, one (better) for iOS 7.x and one for earlier versions of iOS:

    float zoomLevel = 2.0f;
    if ([device respondsToSelector:@selector(setVideoZoomFactor:)]
        && device.activeFormat.videoMaxZoomFactor >= zoomLevel) {
      // iOS 7.x with compatible hardware
      if ([device lockForConfiguration:nil]) {
        [device setVideoZoomFactor:zoomLevel];
        [device unlockForConfiguration];
      }
    } else {
      // Lesser cases
      CGRect frame = captureVideoPreviewLayer.frame;
      float width = frame.size.width * zoomLevel;
      float height = frame.size.height * zoomLevel;
      float x = (frame.size.width - width)/2;
      float y = (frame.size.height - height)/2;
      captureVideoPreviewLayer.bounds = CGRectMake(x, y, width, height);
    }