Отключение автоматического поворота для UIView - PullRequest
21 голосов
/ 21 июля 2010

Мое приложение состоит из панели инструментов и слоя AVCaptureVideoPreviewLayer в фоновом режиме UIView.Мне бы хотелось, чтобы панель инструментов вращалась относительно ориентации устройства, поэтому в моем главном ViewController я реализовал функцию:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait
            || interfaceOrientation == UIInterfaceOrientationLandscapeLeft
            || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

Это работает нормально, но когда ориентация интерфейса изменяется, я вижу, чтофоновый UIView (с видео-слоем) также вращается, поэтому мой просмотр видео теперь воспроизводится на 90 градусов влево или вправо ... Что на самом деле не круто!
Так что мой вопрос: есть ли способ отключить автоанимация вращения на конкретном UIView?

Я видел один похожий вопрос к этому: Отключение автоматического поворота для одного UIView , но ответы не соответствуют моей проблеме, мне действительно нужныв фоновом режиме не перемещаться, чтобы не обойти проблему с помощью своеобразной «встречной анимации».Поэтому я решил поднять эту тему.

Есть идеи?

Спасибо!

Ответы [ 5 ]

11 голосов
/ 02 сентября 2011

Этот пост указал в правильном направлении. Чтобы заставить AVCaptureVideoPreviewLayer не вращаться с устройством, я обернул его в UIView и анимировал этот вид в противоположном направлении:

- (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;
    }];
}

Это кажется немного окольным, но оно оживляет плавно. Другие виды в верхней части слоя предварительного просмотра автоматически поворачиваются, как и должно.

2 голосов
/ 26 февраля 2013

Я наконец нашел здравый ответ на это. Больше не надо возиться с "анимацией вращения" и прочим!

Ключ в том, чтобы использовать UIViewController для слоя предварительного просмотра (не вращающийся вид) и другой для фактического интерфейса. Настройте параметры поворота для обоих, используя shouldAutorotateToInterfaceOrientation: (код приведен в ответах выше):

  • Контроллер предварительного просмотра должен быть установлен, чтобы не вращаться
  • Контроллер интерфейса должен быть повернут в нужную вам ориентацию

Важным моментом является разделение ваших видов путем добавления их непосредственно в окно. Я делаю это в AppDelegate:

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

Это помещает предварительный просмотр видео в фоновом режиме, а затем добавляет вид интерфейса поверх него. Интерфейс можно автоматически поворачивать, не влияя на предварительный просмотр.

Следует отметить одну важную вещь: фон вашего интерфейса должен быть прозрачным, в противном случае он блокирует предварительный просмотр.

2 голосов
/ 21 июля 2010
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  return NO;
}

Или вы сказали отключить его только тогда, когда отображается определенный вид? Если это так, вы можете проверить это, используя метод isDescendantOfView в UIView.

1 голос
/ 22 апреля 2011

Я столкнулся с той же проблемой, хотя простой установки свойства ориентации в AVCaptureVideoPreviewLayer было недостаточно.Дополнительная проблема заключается в том, что CALayer не поддерживает диспетчеры компоновки на iPhone, поэтому кадр видео слоя может быть неправильным при повороте устройства.

Я исправил это с помощью пользовательского UIView, чтобы содержать AVCaptureVideoPreviewLayerзатем я переопределил метод layoutSubviews для этого представления, чтобы гарантировать, что кадр видеослоя всегда установлен правильно.Это также хорошее место для установки свойства ориентации.То есть мой UIView выглядит так:

@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 голосов
/ 21 июля 2010

Попробуйте это:

myVideoCaptureLayer.orientationSupported = NO;
...