Disabling auto rotation for a UIView

前端 未结 5 1825
谎友^
谎友^ 2021-02-05 07:10

My application is composed of a toolbar and an AVCaptureVideoPreviewLayer in a background UIView. I\'d like to see that toolbar rotate regarding the device orientation, so in my

相关标签:
5条回答
  • 2021-02-05 07:35

    I ran into the same issue, though simply setting the orientation property on AVCaptureVideoPreviewLayer was not sufficient. The additional problem is that CALayer does not support layout managers on the iPhone, so the frame of the video layer may be incorrect when the device is rotated.

    I fixed this by using a custom UIView to contain the AVCaptureVideoPreviewLayer and then I overrode the layoutSubviews method for this view to ensure that the video layer's frame is always set correctly. This is also a good place to set the orientation property. That is, my UIView looks like:

    @implementation VideoPreview
    
    @synthesize previewLayer;
    
    - (void) layoutSubviews {
        if (previewLayer) {
            // set the correct orientation for the video layer
            previewLayer.orientation = [[UIDevice currentDevice] orientation];
    
            // and set its frame to that of its parent UIView
            previewLayer.frame = self.bounds;
        }
    }
    
    - (void) addPreviewLayer: (AVCaptureVideoPreviewLayer *) videoLayer {
        previewLayer = videoLayer;
        [self.layer addSublayer:videoLayer];
    }
    
    @end
    
    0 讨论(0)
  • 2021-02-05 07:37
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
      return NO;
    }
    

    Or were you saying to disable it only when a certain view is showing? If so, you can check for this using UIView's isDescendantOfView method.

    0 讨论(0)
  • 2021-02-05 07:43

    I finally found a sane answer for this. No more messing around with "anti-rotation animations" and such!

    The key is to use a UIViewController for your preview layer (the non-rotating view) and another for the actual interface. Configure the rotation options for both using shouldAutorotateToInterfaceOrientation: (the code is in the answers above):

    • The preview view controller should be set to not rotate
    • The interface view controller should be set to rotate to the orientations you need

    The important bit is to keep your views separate by adding them directly to the window. I do this in the AppDelegate:

    [self.window addSubview:previewViewController.view];
    [self.window addSubview:interfaceViewController.view];
    self.window.rootViewController = interfaceViewController;
    [self.window makeKeyAndVisible];
    

    That puts your video preview in the background, and then adds the interface view over it. The interface is free to autorotate without affecting the preview at all.

    One important thing to note: the background of your interface view should be transparent, otherwise it blocks the preview.

    0 讨论(0)
  • 2021-02-05 07:44

    This post pointed in the right direction. To get an AVCaptureVideoPreviewLayer to not rotate with the device I wrapped it in a UIView and animated that view in the opposite direction:

    - (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    
        float rotation;
    
        if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
            rotation = 0;
        } else
        if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
            rotation = M_PI/2;
        } else
        if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
            rotation = -M_PI/2;
        }
    
        [UIView animateWithDuration:duration animations:^{
            cameraPreview.transform = CGAffineTransformMakeRotation(rotation);
            cameraPreview.frame = self.view.frame;
        }];
    }
    

    It seems a little roundabout but it animates smoothly. Other views on top of the preview layer automatically rotate as they should.

    0 讨论(0)
  • 2021-02-05 07:51

    Try this:

    myVideoCaptureLayer.orientationSupported = NO;
    
    0 讨论(0)
提交回复
热议问题