Reputation: 4433
I'm basically after the answer to this question AVCaptureVideoPreviewLayer orientation - need landscape except in Swift.
I'm targeting iOS 8 and AVCaptureVideoPreviewLayer doesn't seem to have a setVideoOrientation function.
How should I be detecting that the orientation has changed, and rotating AVCaptureVideoPreviewLayer appropriately?
Upvotes: 8
Views: 5942
Reputation: 990
Detect and apply it at viewWillLayoutSubviews
or if you're using UIView subclass in layoutSubviews
.
Here's how:
override func viewWillLayoutSubviews() {
let orientation: UIDeviceOrientation = UIDevice.current.orientation
previewLayer.connection?.videoOrientation = {
switch (orientation) {
case .portrait:
return .portrait
case .landscapeRight:
return .landscapeLeft
case .landscapeLeft:
return .landscapeRight
default:
return .portrait
}
}()
}
Upvotes: 24
Reputation: 1030
another solution in Swift 4 it would be using Notification.
NotificationCenter.default.addObserver(self,
selector: #selector(detected),
name:
UIDevice.orientationDidChangeNotification, object: nil)
and in selector function you can check the orientation:
let orientation: UIDeviceOrientation = UIDevice.current.orientation
switch orientation {
case .portrait:
stuff()
case .landscapeLeft:
stuffOther()
case .landscapeRight
stuffOther()
default:
stuffOther()
}
Remember to remove observer when is not necessary.
Very IMPORTANT: your physical iPhone must NOT have lock on rotation (I've lost 2 hour for this because in this case, the method are not intercepted :) ).
Upvotes: 0
Reputation: 355
Xamarin Solution in ViewController;
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
var videoPreviewLayerConnection = PreviewView.VideoPreviewLayer.Connection;
if (videoPreviewLayerConnection != null)
{
var deviceOrientation = UIDevice.CurrentDevice.Orientation;
if (!deviceOrientation.IsPortrait() && !deviceOrientation.IsLandscape())
return;
var newVideoOrientation = VideoOrientationFor(deviceOrientation);
var oldSize = View.Frame.Size;
var oldVideoOrientation = videoPreviewLayerConnection.VideoOrientation;
videoPreviewLayerConnection.VideoOrientation = newVideoOrientation;
}
}
Upvotes: 0
Reputation: 459
For me I need it to change orientation when I rotate iPad left or right, the solution that helped me is:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
let orientation = UIDevice.current.orientation
switch (orientation) {
case .portrait:
videoPreviewLayer?.connection.videoOrientation = .portrait
case .landscapeLeft:
videoPreviewLayer?.connection.videoOrientation = .landscapeRight
case .landscapeRight:
videoPreviewLayer?.connection.videoOrientation = .landscapeLeft
default:
videoPreviewLayer?.connection.videoOrientation = .portrait
}
}
Upvotes: 0
Reputation: 350
update for Swift 3
override func viewWillLayoutSubviews() {
let orientation: UIDeviceOrientation = UIDevice.current.orientation
print(orientation)
switch (orientation) {
case .portrait:
videoPreviewLayer?.connection.videoOrientation = .portrait
case .landscapeRight:
videoPreviewLayer?.connection.videoOrientation = .landscapeLeft
case .landscapeLeft:
videoPreviewLayer?.connection.videoOrientation = .landscapeRight
case .portraitUpsideDown:
videoPreviewLayer?.connection.videoOrientation = .portraitUpsideDown
default:
videoPreviewLayer?.connection.videoOrientation = .portraitUpsideDown
}
}
Upvotes: 1