2015-05-12 139 views
4

我有兩個視圖控制器。一個是根VC,包含諸如錄製按鈕之類的UI界面。在此視圖控制器上,我還顯示索引0處的另一個VC的視圖。此視圖包含AVCaptureVideoPreviewLayer。防止AVCaptureVideoPreviewLayer旋轉,但允許UI層以方向旋轉

我希望我的攝像機能夠模仿Apple視頻攝像頭應用程序,其中界面佈局隨旋轉進行調整,但視頻預覽圖層不支持。您可以看到股票視頻應用程序中的錄製計時器(UILabel)如何消失並在頂部重新顯示,具體取決於方向。

任何想法如何做到這一點?我發現一個建議,建議將預覽添加到應用程序委託的窗口,因爲它不符合導航控制器的旋轉,但它不適用於我。

謝謝!

回答

6

務必將shouldAutorotate返回false:該方向改變通知

-(BOOL)shouldAutorotate{ 
    return NO; 
} 

寄存器:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(orientationChanged:) 
              name:UIDeviceOrientationDidChangeNotification 
              object:nil]; 

實現通知改變

-(void)orientationChanged:(NSNotification *)notif { 
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation]; 

// Calculate rotation angle 
CGFloat angle; 
switch (deviceOrientation) { 
    case UIDeviceOrientationPortraitUpsideDown: 
     angle = M_PI; 
     break; 
    case UIDeviceOrientationLandscapeLeft: 
     angle = M_PI_2; 
     break; 
    case UIDeviceOrientationLandscapeRight: 
     angle = - M_PI_2; 
     break; 
    default: 
     angle = 0; 
     break; 
} 


} 

並旋轉UI

[UIView animateWithDuration:.3 animations:^{ 
     self.closeButton.transform = CGAffineTransformMakeRotation(angle); 
     self.gridButton.transform = CGAffineTransformMakeRotation(angle); 
     self.flashButton.transform = CGAffineTransformMakeRotation(angle); 
    } completion:^(BOOL finished) { 

}]; 

我這是怎麼實現的屏幕被鎖定,但旋轉UI,如果這個作品鏈接棧後,我可以在那裏複製它,你可以勾選它:P

1

在顯示攝像機輸出添加視圖:

AVCaptureVideoPreviewLayer *layer = (AVCaptureVideoPreviewLayer *)self.layer; 
if ([layer.connection isVideoOrientationSupported]) { 
    [layer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait]; 
    } 

AVCaptureVideoOrientationPortrait只是其中的一個選項。您可以從以下選擇:

typedef NS_ENUM(NSInteger, AVCaptureVideoOrientation) { 
    AVCaptureVideoOrientationPortrait   = 1, 
    AVCaptureVideoOrientationPortraitUpsideDown = 2, 
    AVCaptureVideoOrientationLandscapeRight  = 3, 
    AVCaptureVideoOrientationLandscapeLeft  = 4, 
} 

這必須您設置的會議後進行

4

我有一個非常類似的情況。我只有一個視圖控制器,我想要有一個不旋轉的AVCaptureVideoPreviewLayer。我發現@ SeanLintern88接受的解決方案並不適合我;狀態欄從未移動,我在屏幕上顯示的WKWebView沒有正確調整大小。

我碰到的一個更大的問題是,我在視圖控制器視圖中放入了我的AVCaptureVideoPreviewLayer。創建一個新的UIView只是爲了保存圖層要好得多。

之後,我從Apple QA1890: Preventing a View From Rotating發現技術說明。這讓我產生以下SWIFT代碼:

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 
     }) 
} 

原來的技術說明中沒有行self.previewView!.layer.frame = self.view.bounds但我發現很必要的,因爲雖然定位點不動,框架了。沒有這一行,預覽將被抵消。另外,由於我正在做所有的工作,將視圖保持在正確的位置,所以我不得不移除所有的定位約束條件。當我把它們放入時,它們會導致預覽反而在相反的方向上偏移。