I have a very similar situation. I just have one view controller and I want to have a AVCaptureVideoPreviewLayer
that doesn't rotate in it. I found the accepted solution by @SeanLintern88 did not work for me; the status bar never moved and the WKWebView I had on the screen was not getting resizes properly.
One of the bigger issues I ran into was that I was putting my AVCaptureVideoPreviewLayer
in the view controller's view. It is much better to create a new UIView
just to hold the layer.
After that I found a technical note from Apple QA1890: Preventing a View From Rotating. This allowed me to produce the following swift code:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
{
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
coordinator.animateAlongsideTransition(
{ (UIViewControllerTransitionCoordinatorContext) in
let deltaTransform = coordinator.targetTransform()
let deltaAngle = atan2f(Float(deltaTransform.b), Float(deltaTransform.a))
var currentRotation : Float = (self.previewView!.layer.valueForKeyPath("transform.rotation.z")?.floatValue)!
// Adding a small value to the rotation angle forces the animation to occur in a the desired direction, preventing an issue where the view would appear to rotate 2PI radians during a rotation from LandscapeRight -> LandscapeLeft.
currentRotation += -1 * deltaAngle + 0.0001;
self.previewView!.layer.setValue(currentRotation, forKeyPath: "transform.rotation.z")
self.previewView!.layer.frame = self.view.bounds
},
completion:
{ (UIViewControllerTransitionCoordinatorContext) in
// Integralize the transform to undo the extra 0.0001 added to the rotation angle.
var currentTransform : CGAffineTransform = self.previewView!.transform
currentTransform.a = round(currentTransform.a)
currentTransform.b = round(currentTransform.b)
currentTransform.c = round(currentTransform.c)
currentTransform.d = round(currentTransform.d)
self.previewView!.transform = currentTransform
})
}
The original tech note did not have the line self.previewView!.layer.frame = self.view.bounds
but I found that very necessary because although the anchor point doesn't move, the frame has. Without that line, the preview will be offset.
Also, since I am doing all of the work keeping the view in the correct position, I had to remove all the positioning constraints on it. When I had them in, they would cause the preview to instead be offset in the opposite direction.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…