Search code examples
iosswiftavcapture

AVCaptureVideoPreviewLayer rotation not working


when i rotate my device from landscape left to landscape right or vice-versa, the AVCaptureVideoPreviewLayer turns upside-down. it works perfectly fine, when I rotate my device from portrait to landscape mode. this is my code

{    override func viewWillLayoutSubviews() {
        let orientation: UIDeviceOrientation = UIDevice.currentDevice().orientation
        if(buttonsview.isDescendantOfView(self.view)){
            buttonsview.removeFromSuperview()
        }else{

        }
        switch (orientation)
        {
        case .Portrait:
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
            previewLayer.frame = self.view.bounds
            var frame = buttonsview.frame
            frame.size.width = 320
            frame.size.height = 50
            let totalWidth : CGFloat = self.view.bounds.size.width
            var x:CGFloat = 0.0;
            if( totalWidth>320)
            {
                x = (totalWidth-320.0)/2.0
            }
            frame.origin.x = x
            frame.origin.y = self.view.bounds.size.height-50
            buttonsview.frame = frame
            buttonsview.layoutSubviews()
            view.addSubview(buttonsview)
             self.activityView.center = self.view.center
            break
        case .LandscapeRight:
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.LandscapeLeft
            previewLayer.frame = self.view.bounds
            var frame = buttonsview.frame
            frame.size.width = 320
            frame.size.height = 50
            let totalWidth : CGFloat = self.view.bounds.size.width
            var x:CGFloat = 0.0;
            if( totalWidth>320)
            {
                x = (totalWidth-320.0)/2.0
            }
            frame.origin.x = x
            frame.origin.y = self.view.bounds.size.height-50
            buttonsview.frame = frame
            view.addSubview(buttonsview)
             self.activityView.center = self.view.center
            break
        case .LandscapeLeft:
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.LandscapeRight
            previewLayer.frame = self.view.bounds
            var frame = buttonsview.frame
            frame.size.width = 320
            frame.size.height = 50
            let totalWidth : CGFloat = self.view.bounds.size.width
            var x:CGFloat = 0.0;
            if( totalWidth>320)
            {
                x = (totalWidth-320.0)/2.0
            }
            frame.origin.x = x
            frame.origin.y = self.view.bounds.size.height-50
            buttonsview.frame = frame
            view.addSubview(buttonsview)
             self.activityView.center = self.view.center
            break

        case .PortraitUpsideDown:
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.PortraitUpsideDown
            previewLayer.frame = self.view.bounds
            var frame = buttonsview.frame
            frame.size.width = 320
            frame.size.height = 50
            let totalWidth : CGFloat = self.view.bounds.size.width
            var x:CGFloat = 0.0;
            if( totalWidth>320)
            {
                x = (totalWidth-320.0)/2.0
            }
            frame.origin.x = x
            frame.origin.y = self.view.bounds.size.height-50
            buttonsview.frame = frame
            buttonsview.layoutSubviews()
            view.addSubview(buttonsview)
            self.activityView.center = self.view.center
            break



        case .Unknown:
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.LandscapeLeft
            previewLayer.frame = self.view.bounds
            var frame = buttonsview.frame
            frame.size.width = 320
            frame.size.height = 50
            let totalWidth : CGFloat = self.view.bounds.size.width
            var x:CGFloat = 0.0;
            if( totalWidth>320)
            {
                x = (totalWidth-320.0)/2.0
            }
            frame.origin.x = x
            frame.origin.y = self.view.bounds.size.height-50
            buttonsview.frame = frame
            buttonsview.layoutSubviews()
            view.addSubview(buttonsview)
            self.activityView.center = self.view.center
            break

        default:
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
            previewLayer.frame = self.view.bounds
            var frame = buttonsview.frame
            frame.size.width = 320
            frame.size.height = 50
            let totalWidth : CGFloat = self.view.bounds.size.width
            var x:CGFloat = 0.0;
            if( totalWidth>320)
            {
                x = (totalWidth-320.0)/2.0
            }
            frame.origin.x = x
            frame.origin.y = self.view.bounds.size.height-50
            buttonsview.frame = frame
            buttonsview.layoutSubviews()
            view.addSubview(buttonsview)
             self.activityView.center = self.view.center
            break
        }
    }
}

Solution

  • finally done it.

    override func viewDidLayoutSubviews() {
            var newOrientation: AVCaptureVideoOrientation
            var orientation: UIDeviceOrientation = UIDevice.currentDevice().orientation
            switch (orientation) {
            case .Portrait:
                newOrientation = .Portrait;
                var frame = buttonsview.frame
                frame.size.width = 320
                frame.size.height = 50
                let totalWidth : CGFloat = self.view.bounds.size.width
                var x:CGFloat = 0.0;
                if( totalWidth>320)
                {
                    x = (totalWidth-320.0)/2.0
                }
                frame.origin.x = x
                frame.origin.y = self.view.bounds.size.height-50
                buttonsview.frame = frame
                buttonsview.layoutSubviews()
                view.addSubview(buttonsview)
                self.activityView.center = self.view.center
                break;
    
            case .PortraitUpsideDown:
                newOrientation = .PortraitUpsideDown;
                var frame = buttonsview.frame
                frame.size.width = 320
                frame.size.height = 50
                let totalWidth : CGFloat = self.view.bounds.size.width
                var x:CGFloat = 0.0;
                if( totalWidth>320)
                {
                    x = (totalWidth-320.0)/2.0
                }
                frame.origin.x = x
                frame.origin.y = self.view.bounds.size.height-50
                buttonsview.frame = frame
                buttonsview.layoutSubviews()
                view.addSubview(buttonsview)
                self.activityView.center = self.view.center
                break
    
            case .LandscapeLeft:
                newOrientation = .LandscapeRight;
                var frame = buttonsview.frame
                frame.size.width = 320
                frame.size.height = 50
                let totalWidth : CGFloat = self.view.bounds.size.width
                var x:CGFloat = 0.0;
                if( totalWidth>320)
                {
                    x = (totalWidth-320.0)/2.0
                }
                frame.origin.x = x
                frame.origin.y = self.view.bounds.size.height-50
                buttonsview.frame = frame
                view.addSubview(buttonsview)
                self.activityView.center = self.view.center
                break
    
            case .LandscapeRight:
                newOrientation = .LandscapeLeft;
    
                var frame = buttonsview.frame
                frame.size.width = 320
                frame.size.height = 50
                let totalWidth : CGFloat = self.view.bounds.size.width
                var x:CGFloat = 0.0;
                if( totalWidth>320)
                {
                    x = (totalWidth-320.0)/2.0
                }
                frame.origin.x = x
                frame.origin.y = self.view.bounds.size.height-50
                buttonsview.frame = frame
                view.addSubview(buttonsview)
                self.activityView.center = self.view.center
                break;
            default:
                newOrientation = .Portrait;
                var frame = buttonsview.frame
                frame.size.width = 320
                frame.size.height = 50
                let totalWidth : CGFloat = self.view.bounds.size.width
                var x:CGFloat = 0.0;
                if( totalWidth>320)
                {
                    x = (totalWidth-320.0)/2.0
                }
                frame.origin.x = x
                frame.origin.y = self.view.bounds.size.height-50
                buttonsview.frame = frame
                buttonsview.layoutSubviews()
                view.addSubview(buttonsview)
                self.activityView.center = self.view.center
              }
    
            let newSize = self.view.bounds.size;
            previewLayer.position = CGPointMake(0.5 * newSize.width, 0.5 * newSize.height);
        }
    
        override func willAnimateRotationToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
            CATransaction.begin()
            CATransaction.setAnimationDuration(duration)
            CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut));
            updatePreviewLayerForOrientation(toInterfaceOrientation);
            CATransaction.commit();
        }
    
        func updatePreviewLayerForOrientation(interfaceOrientation: UIInterfaceOrientation)
        {
            // Correct position of previewLayer
            let newSize = view.bounds.size;
            previewLayer.position = CGPointMake(0.5 * newSize.width, 0.5 * newSize.height);
            var angle: Double!
            // Rotate the previewLayer, in order to have camera picture right
            switch interfaceOrientation {
            case .Portrait:
                angle = 0
    
    
            case .LandscapeLeft:
                angle = M_PI/2
            case .LandscapeRight:
                angle = -M_PI/2
            default: // .PortraitUpsideDown
                angle = M_PI
            }
    
            previewLayer.setAffineTransform(CGAffineTransformMakeRotation(CGFloat(angle)))
        }