AVCaptureVideoPreviewLayer 방향-가로 방향 필요
내 앱은 가로 모드입니다. 다음과 같이 AVCaptureVideoPreviewLayer를 제공합니다.
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[self.previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
NSLog(@"previewView: %@", self.previewView);
CALayer *rootLayer = [self.previewView layer];
[rootLayer setMasksToBounds:YES];
[self.previewLayer setFrame:[rootLayer bounds]];
NSLog(@"previewlayer: %f, %f, %f, %f", self.previewLayer.frame.origin.x, self.previewLayer.frame.origin.y, self.previewLayer.frame.size.width, self.previewLayer.frame.size.height);
[rootLayer addSublayer:self.previewLayer];
[session startRunning];
self.previewView의 프레임은 (0,0,568,320)입니다. self.previewLayer는 이론적으로 올바른 (0,0,568,320) 프레임을 기록합니다. 그러나 카메라 디스플레이는 가로 화면 중앙에 세로 직사각형으로 나타나고 카메라 미리보기 이미지의 방향이 90도 잘못되었습니다. 내가 도대체 뭘 잘못하고있는 겁니까? 가로 모드에서 전체 화면으로 표시하려면 카메라 미리보기 레이어가 필요하며 이미지 방향이 올바르게 지정되어야합니다.
기본 카메라 방향은 가로 왼쪽 (왼쪽에 홈 버튼)입니다. 여기서 두 가지 작업을 수행해야합니다.
1- previewLayer 프레임을 다음으로 변경하십시오.
self.previewLayer.frame=self.view.bounds;
화면이 회전 할 때 미리보기 레이어의 프레임이 변경되도록 미리보기 레이어 프레임을 화면의 경계로 설정해야합니다 (루트 뷰의 프레임은 회전에 따라 변경되지 않고 루트 뷰의 경계가 변경되므로 사용할 수 없습니다. 하다). 귀하의 예에서는 previewlayer 프레임을 내가 보지 못하는 previewView 속성으로 설정하고 있습니다.
2- 장치 회전과 함께 미리보기 레이어 연결을 회전해야합니다. viewDidAppear에 다음 코드를 추가합니다.
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
//Get Preview Layer connection
AVCaptureConnection *previewLayerConnection=self.previewLayer.connection;
if ([previewLayerConnection isVideoOrientationSupported])
[previewLayerConnection setVideoOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
이것이 해결되기를 바랍니다.
전체 공개 : 가로가 오른쪽인지 가로가 왼쪽인지 상관하지 않기 때문에 단순화 된 버전입니다.
SWIFT 3.0 및 XCODE 8.0에 대한 최상의 답변
private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
layer.videoOrientation = orientation
previewLayer.frame = self.view.bounds
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let connection = self.previewLayer?.connection {
let currentDevice: UIDevice = UIDevice.current
let orientation: UIDeviceOrientation = currentDevice.orientation
let previewLayerConnection : AVCaptureConnection = connection
if previewLayerConnection.isVideoOrientationSupported {
switch (orientation) {
case .portrait: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break
case .landscapeRight: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeLeft)
break
case .landscapeLeft: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeRight)
break
case .portraitUpsideDown: updatePreviewLayer(layer: previewLayerConnection, orientation: .portraitUpsideDown)
break
default: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break
}
}
}
}
SWIFT 2.2 및 XCODE 7.3에 대한 최상의 답변
private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
layer.videoOrientation = orientation
previewLayer.frame = self.view.bounds
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let connection = self.previewLayer?.connection {
let currentDevice: UIDevice = UIDevice.currentDevice()
let orientation: UIDeviceOrientation = currentDevice.orientation
let previewLayerConnection : AVCaptureConnection = connection
if (previewLayerConnection.supportsVideoOrientation) {
switch (orientation) {
case .Portrait: updatePreviewLayer(previewLayerConnection, orientation: .Portrait)
break
case .LandscapeRight: updatePreviewLayer(previewLayerConnection, orientation: .LandscapeLeft)
break
case .LandscapeLeft: updatePreviewLayer(previewLayerConnection, orientation: .LandscapeRight)
break
case .PortraitUpsideDown: updatePreviewLayer(previewLayerConnection, orientation: .PortraitUpsideDown)
break
default: updatePreviewLayer(previewLayerConnection, orientation: .Portrait)
break
}
}
}
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
if let connection = self.previewLayer?.connection {
var currentDevice: UIDevice = UIDevice.currentDevice()
var orientation: UIDeviceOrientation = currentDevice.orientation
var previewLayerConnection : AVCaptureConnection = connection
if (previewLayerConnection.supportsVideoOrientation) {
switch (orientation) {
case .portrait:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.portrait
case .landscapeRight:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.landscapeRight
case .landscapeLeft:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.landscapeLeft
case .portraitUpsideDown:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.portraitUpsideDown
default:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.portrait
}
}
}
}
우리는 사용할 수 없습니다
[previewLayerConnection setVideoOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
때문에 UIInterfaceOrientation != AVCaptureVideoOrientation
그러나 우리는 값을 테스트 할 수 있습니다. 다음 코드로이 작업을 수행합니다.
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
switch (orientation) {
case UIInterfaceOrientationPortrait:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortraitUpsideDown];
break;
case UIInterfaceOrientationLandscapeLeft:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
break;
case UIInterfaceOrientationLandscapeRight:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
break;
}
}
API가 다소 변경된 것 같습니다. videoOrientation
이제 미리보기 레이어의 connection
속성 에 대한 속성입니다. 또한 스위치를 사용할 필요가 없습니다. Swift 3.0에 대한 답변 :
override func viewDidLayoutSubviews() {
self.configureVideoOrientation()
}
private func configureVideoOrientation() {
if let previewLayer = self.previewLayer,
let connection = previewLayer.connection {
let orientation = UIDevice.current.orientation
if connection.isVideoOrientationSupported,
let videoOrientation = AVCaptureVideoOrientation(rawValue: orientation.rawValue) {
previewLayer.frame = self.view.bounds
connection.videoOrientation = videoOrientation
}
}
}
완전한 기능의 카메라 미리보기에 어려움을 겪고있는 모든 사람을위한 것입니다. 다음은 생산 코드입니다. 물론 단점은 방향이 변경 될 때 지연된다는 것입니다. 이 문제를 극복 할 수있는 더 나은 솔루션이 있다면 공유 해주세요.
- (void)viewDidLoad
{
[super viewDidLoad];
[self initCamera];
}
- (void)initCamera
{
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:nil];
if (captureInput) {
mSession = [[AVCaptureSession alloc] init];
[mSession addInput:captureInput];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
if ([mSession isRunning]) {
[mSession stopRunning];
[mCameraLayer removeFromSuperlayer];
[self initCamera];
[self startCamera];
}
}
- (void)startCamera
{
[mSession startRunning];
Settings::getInstance()->setClearColor(Color(0, 0, 0, 0));
mCameraLayer = [AVCaptureVideoPreviewLayer layerWithSession: mSession];
[self updateCameraLayer];
[mCameraView.layer addSublayer:mCameraLayer];
}
- (void)stopCamera
{
[mSession stopRunning];
[mCameraLayer removeFromSuperlayer];
Settings::getInstance()->setDefClearColor();
}
- (void)toggleCamera
{
mSession.isRunning ? [self stopCamera] : [self startCamera];
[mGLKView setNeedsDisplay];
}
- (void)updateCameraLayer
{
mCameraLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
mCameraLayer.frame = mCameraView.bounds;
float x = mCameraView.frame.origin.x;
float y = mCameraView.frame.origin.y;
float w = mCameraView.frame.size.width;
float h = mCameraView.frame.size.height;
CATransform3D transform = CATransform3DIdentity;
if (UIDeviceOrientationLandscapeLeft == [[UIDevice currentDevice] orientation]) {
mCameraLayer.frame = CGRectMake(x, y, h, w);
transform = CATransform3DTranslate(transform, (w - h) / 2, (h - w) / 2, 0);
transform = CATransform3DRotate(transform, -M_PI/2, 0, 0, 1);
} else if (UIDeviceOrientationLandscapeRight == [[UIDevice currentDevice] orientation]) {
mCameraLayer.frame = CGRectMake(x, y, h, w);
transform = CATransform3DTranslate(transform, (w - h) / 2, (h - w) / 2, 0);
transform = CATransform3DRotate(transform, M_PI/2, 0, 0, 1);
} else if (UIDeviceOrientationPortraitUpsideDown == [[UIDevice currentDevice] orientation]) {
mCameraLayer.frame = mCameraView.bounds;
transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
} else {
mCameraLayer.frame = mCameraView.bounds;
}
mCameraLayer.transform = transform;
}
enter code here
위의 솔루션을 사용하는 사용 중단 및 변환 경고가 있고 videoOrientation 설정이 iOS7에서 작동하지 않는 것 같았 기 때문에 AVCaptureVideoPreviewLayer에 대한 getter에 다음과 같이 방향을 확인합니다.
- (AVCaptureVideoPreviewLayer *) previewLayer
{
if(!_previewLayer)
{
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession: self.captureSession];
[_previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
_previewLayer.frame = self.view.bounds; // Assume you want the preview layer to fill the view.
[_previewLayer setPosition:CGPointMake(0,0)];
if (UIDeviceOrientationLandscapeLeft == [[UIDevice currentDevice] orientation]) {
_previewLayer.transform = CATransform3DMakeRotation(-M_PI/2, 0, 0, 1);
}
else if (UIDeviceOrientationLandscapeRight == [[UIDevice currentDevice] orientation])
{
_previewLayer.transform = CATransform3DMakeRotation(M_PI/2, 0, 0, 1);
}
}
return _previewLayer;
}
Swift 4, Xcode 9에서 작동합니다.
override func viewWillTransition(to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator)
{
super.viewWillTransition(to: size, with: coordinator)
guard
let conn = self.previewLayer?.connection,
conn.isVideoOrientationSupported
else { return }
let deviceOrientation = UIDevice.current.orientation
switch deviceOrientation {
case .portrait: conn.videoOrientation = .portrait
case .landscapeRight: conn.videoOrientation = .landscapeLeft
case .landscapeLeft: conn.videoOrientation = .landscapeRight
case .portraitUpsideDown: conn.videoOrientation = .portraitUpsideDown
default: conn.videoOrientation = .portrait
}
}
여기서 주목해야 할 한 가지 미묘한 점 UIDeviceOrientation.landscapeRight
은 AVCaptureVideoOrientation.landscapeLeft
.
다른 가로 사례도 비슷하게 일치하지 않습니다. 이것은 의도적이며 UIKit과 AVFoundation 간의 불행한 불일치를 수용합니다. 이름을 일치시켜 케이스를 일치 시키면 작동하지 않으며 가로 구성에서 동영상이 거꾸로 표시됩니다.
에서 UIDeviceOrientation
로의 올바른 매핑 AVCaptureVideoOrientation
이 필요합니다.
앱 지원하는 경우 device rotation
, resizing preview.frame
필요하다, 이것은 func
호출해야 viewDidLayoutSubviews()
하고 viewWillTransition()
.
private func configureVideoOrientation() {
if let preview = self.previewLayer,
let connection = preview.connection {
let orientation = UIDevice.current.orientation
if connection.isVideoOrientationSupported {
var videoOrientation: AVCaptureVideoOrientation
switch orientation {
case .portrait:
videoOrientation = .portrait
case .portraitUpsideDown:
videoOrientation = .portraitUpsideDown
case .landscapeLeft:
videoOrientation = .landscapeRight
case .landscapeRight:
videoOrientation = .landscapeLeft
default:
videoOrientation = .portrait
}
preview.frame = self.view.bounds
connection.videoOrientation = videoOrientation
}
}
}
Hey Guys에 대한 모든 답변과 피드백에 감사드립니다. 저는 신속한 앱을 작업하면서 이것을 발견했습니다. 다음 코드를 사용하여 카메라가 장치와 함께 회전하도록 할 수 있습니다.
override func shouldAutorotate() -> Bool {
if your cameraController.previewLayer.connection != nil {
var currentDevice: UIDevice = UIDevice.currentDevice()
var orientation: UIDeviceOrientation = currentDevice.orientation
var previewLayerConnection : AVCaptureConnection = your cameraController.previewLayer.connection
if (previewLayerConnection.supportsVideoOrientation)
{
switch (orientation)
{
case .Portrait:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.Portrait
break
case .LandscapeRight:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.LandscapeLeft
break
case .LandscapeLeft:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.LandscapeRight
break
default:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.Portrait
break
}
}
}
return true
}
도움이 되었기를 바랍니다!
먼저 AVCaptureVideoPreviewLayer를 만들고 다음을 수행해야합니다.
- videoGravity를 설정하십시오 (내 경우에는 비디오 출력을 얻기 위해 작은보기를 사용하고 있음).
프레임을 설정하십시오.
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; [_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
처음에 방향 설정
if (_videoPreviewLayer.connection.supportsVideoOrientation) { _videoPreviewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation:[UIApplication sharedApplication].statusBarOrientation]; }
간단한 스위치 케이스를 사용하여 각 케이스의 방향 설정
-(AVCaptureVideoOrientation)interfaceOrientationToVideoOrientation:
(UIInterfaceOrientation)orientation { switch (orientation) { case UIInterfaceOrientationPortrait: return AVCaptureVideoOrientationPortrait; case UIInterfaceOrientationPortraitUpsideDown: return AVCaptureVideoOrientationPortraitUpsideDown; case UIInterfaceOrientationLandscapeLeft: return AVCaptureVideoOrientationLandscapeLeft ; case UIInterfaceOrientationLandscapeRight: return AVCaptureVideoOrientationLandscapeRight; default: break; } NSLog(@"Warning - Didn't recognise interface orientation (%d)",orientation); return AVCaptureVideoOrientationPortrait;
}
- 기기가 landscapeLeft 및 landscapeRight를 모두 지원하므로 회전시 호출되는 대리자를 사용합니다.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ if (_videoPreviewLayer.connection.supportsVideoOrientation) { _videoPreviewLayer.connection.videoOrientation = [self interfaceOrientationToVideoOrientation:toInterfaceOrientation]; } }
나도 똑같은 얼굴을하고 있었는데 이것은 내 카메라 방향을 수정하는 것이 었습니다.
override func shouldAutorotate() -> Bool {
return false
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
return UIInterfaceOrientation.LandscapeLeft
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.LandscapeLeft
}
카메라를 고치려면
let previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.avCaptureSession)
previewLayer.frame = self.view.layer.frame
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
Maselko의 답변 은 상태 표시 줄 방향이 뒤집 히면 카메라 출력이 거꾸로 표시된다는 점을 제외하면 거의 저에게 효과적이었습니다 . 상태 표시 줄이 뒤집힐 때 Maselko의 논리를 다시 호출하여이 문제를 해결했습니다.
다음은 수정 된 Maselko 솔루션입니다 (ios12 / swift4에서 테스트 됨).
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setCameraOrientation()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
setCameraOrientation()
}
@objc func setCameraOrientation() {
if let connection = self.previewLayer?.connection {
let currentDevice: UIDevice = UIDevice.current
let orientation: UIDeviceOrientation = currentDevice.orientation
let previewLayerConnection : AVCaptureConnection = connection
if previewLayerConnection.isVideoOrientationSupported {
let o: AVCaptureVideoOrientation
switch (orientation) {
case .portrait: o = .portrait
case .landscapeRight: o = .landscapeLeft
case .landscapeLeft: o = .landscapeRight
case .portraitUpsideDown: o = .portraitUpsideDown
default: o = .portrait
}
previewLayerConnection.videoOrientation = o
previewLayer!.frame = self.view.bounds
}
}
}
Swift 4.2-Xcode 10.0-iOS 12.0에서 작동하는 선택된 답변 :
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let previewLayerConnection = self.videoPreviewLayer?.connection, previewLayerConnection.isVideoOrientationSupported {
updatePreviewLayer(layer: previewLayerConnection, orientation: UIApplication.shared.statusBarOrientation.videoOrientation)
}
}
private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
layer.videoOrientation = orientation
videoPreviewLayer?.frame = self.view.bounds
}
UIInterfaceOrientation에서 AVCaptureVideoOrientation으로의 매핑을 잊지 마십시오.
extension UIInterfaceOrientation {
public var videoOrientation: AVCaptureVideoOrientation {
switch self {
case .portrait:
return AVCaptureVideoOrientation.portrait
case .landscapeRight:
return AVCaptureVideoOrientation.landscapeRight
case .landscapeLeft:
return AVCaptureVideoOrientation.landscapeLeft
case .portraitUpsideDown:
return AVCaptureVideoOrientation.portraitUpsideDown
default:
return AVCaptureVideoOrientation.portrait
}
}
}
Swift 5 버전
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updatePreview()
}
func updatePreview() {
let orientation: AVCaptureVideoOrientation
switch UIDevice.current.orientation {
case .portrait:
orientation = .portrait
case .landscapeRight:
orientation = .landscapeLeft
case .landscapeLeft:
orientation = .landscapeRight
case .portraitUpsideDown:
orientation = .portraitUpsideDown
default:
orientation = .portrait
}
if previewLayer?.connection?.isVideoOrientationSupported == true {
previewLayer?.connection?.videoOrientation = orientation
}
previewLayer.frame = view.bounds
}
iOS 8 ~ 11.1에서 문제없이 작동하는 유일한 방법은이 작업을 수행하는 것이며, 제 경우에는 애플리케이션을 가로 모드로만로드했지만 모든 방향에서 작동해야한다는 점을 언급해야합니다. imageview를 통해 수동으로 카메라 또는 원하는 모든 것을 매우 쉽게)
@interface ViewController (){
AVCaptureVideoPreviewLayer * previewLayer;
AVCaptureSession* session;
}
@property (weak, nonatomic) IBOutlet UIView *cameraPreviewView;
-(void)viewDidLoad{
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:nil];
if (captureInput) {
session = [[AVCaptureSession alloc] init];
[session addInput:captureInput];
}
previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
CALayer *rootLayer = [self.cameraPreviewView layer];
[rootLayer setMasksToBounds:YES];
[previewLayer setFrame:[self.view bounds]];
[rootLayer addSublayer:previewLayer];
[session startRunning];
//Orientation Code is in viewDidLayoutSubviews method
}
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
switch (orientation) {
case UIInterfaceOrientationPortrait:
[previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortraitUpsideDown];
break;
case UIInterfaceOrientationLandscapeLeft:
[previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
break;
case UIInterfaceOrientationLandscapeRight:
[previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
break;
default:break;
}
}
@Maselko의 대답은 정확하지만 한 가지 이유는 장치 방향이 장치가 물리적으로 배치되는 방식이기 때문에 UIApplication.shared.statusBarOrientation
대신을 사용해야합니다 . 장치가 가로 모드에 있지만 UI가 해당 방향을 지원하지 않을 때 중단됩니다 (예 : 가로 전용 카메라 앱을 만들고 장치가 세로 위치에있을 때보기를 시작하는 경우).UIDevice.current.orientation
private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
layer.videoOrientation = orientation
previewLayer.frame = self.view.bounds
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let connection = self.previewLayer?.connection {
let currentDevice: UIDevice = UIDevice.current
let orientation = UIApplication.shared.statusBarOrientation
let previewLayerConnection : AVCaptureConnection = connection
if previewLayerConnection.isVideoOrientationSupported {
switch (orientation) {
case .portrait: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break
case .landscapeRight: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeLeft)
break
case .landscapeLeft: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeRight)
break
case .portraitUpsideDown: updatePreviewLayer(layer: previewLayerConnection, orientation: .portraitUpsideDown)
break
default: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break
}
}
}
}
다음은 Swift 4에서 사용중인 솔루션입니다.
짧고 아름답게 작동합니다.
open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let videoLayer = self.previewLayer
coordinator.animate(alongsideTransition: { (context: UIViewControllerTransitionCoordinatorContext) in
guard let connection = videoLayer?.connection, connection.isVideoOrientationSupported, let orientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue) else {
return
}
connection.videoOrientation = orientation
videoLayer?.frame = self.view.bounds
}) { (context: UIViewControllerTransitionCoordinatorContext) in
// handle any completion logic here...
}
}
Maselko의 답변 개선 버전
Works just great!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let connection = previewView.connection {
if connection.isVideoOrientationSupported {
let videoOrientation = AVCaptureVideoOrientation.init(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!
connection.videoOrientation = videoOrientation
previewView.frame = self.view.bounds
}
}
}
ReferenceURL : https://stackoverflow.com/questions/15075300/avcapturevideopreviewlayer-orientation-need-landscape
'development' 카테고리의 다른 글
애플리케이션 컨텍스트와 함께 글라이드 이미지 로딩 (0) | 2020.12.27 |
---|---|
Gson :지도를 직렬화하는 더 쉬운 방법이 있습니까? (0) | 2020.12.27 |
performFetchWithCompletionHandler가 실행되지 않습니다. (0) | 2020.12.27 |
목표 C-두 날짜 사이의 일수 계산 (0) | 2020.12.27 |
함수 호출에 너무 많은 인수 (예상 0)가 3 개 있습니다. (0) | 2020.12.27 |