Подтвердить что ты не робот

Отключить вращение в UIImagePicker

Здравствуйте, мне нужно отключить вращение UIImagePicker.
Если пользователь снимется, когда iPhone находится на "пейзаже", кнопки будут вращаться, и сделанное изображение также будет повернуто. Я хочу отключить этот параметр, чтобы акселерометр не работал, и он всегда будет выглядеть как в портретном режиме.
Как я могу это сделать?
Спасибо, Матан Радомский.

4b9b3361

Ответ 1

Здесь решение: [UIDevice endGeneratingDeviceOrientationNotifications].

Почему так трудно найти? Две причины:

  • UIDevice подсчитывает количество включений или отключений ориентации уведомлений. Если он был включен больше времени, чем отключен, уведомления будут выдаваться.
  • UIImagePickerController включает эти уведомления, когда они представлены.

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

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

@try 
{
    // Create a UIImagePicker in camera mode.
    UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease]; 
    picker.sourceType = UIImagePickerControllerSourceTypeCamera;  
    picker.delegate = self; 

    // Prevent the image picker learning about orientation changes by preventing the device from reporting them.
    UIDevice *currentDevice = [UIDevice currentDevice];

    // The device keeps count of orientation requests.  If the count is more than one, it continues detecting them and sending notifications.  So, switch them off repeatedly until the count reaches zero and they are genuinely off.
    // If orientation notifications are on when the view is presented, it may slide on in landscape mode even if the app is entirely portrait.
    // If other parts of the app require orientation notifications, the number "end" messages sent should be counted.  An equal number of "begin" messages should be sent after the image picker ends.
    while ([currentDevice isGeneratingDeviceOrientationNotifications])
        [currentDevice endGeneratingDeviceOrientationNotifications];

    // Display the camera.
    [self presentModalViewController:picker animated:YES];

    // The UIImagePickerController switches on notifications AGAIN when it is presented, so switch them off again.
    while ([currentDevice isGeneratingDeviceOrientationNotifications])
        [currentDevice endGeneratingDeviceOrientationNotifications];
}
@catch (NSException *exception) 
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Camera" message:@"Camera is not available" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
    [alert show];
    [alert release];
}

Как отмечено выше, сделанные снимки могут по-прежнему находиться в неправильной ориентации. Если вы хотите, чтобы они были ориентированы последовательно, проверьте их соотношение сторон и повернуть соответственно. Я рекомендую этот ответ: Как повернуть UIImage на 90 градусов?

//assume that the image is loaded in landscape mode from disk
UIImage * landscapeImage = [UIImage imageNamed: imgname];
UIImage * portraitImage = [[UIImage alloc] initWithCGImage: landscapeImage.CGImage scale:1.0 orientation: UIImageOrientationLeft] autorelease];

Ответ 2

В 2010 году Как предотвратить поворот модального UIImagePickerController? не нашел счастливого ответа на этот вопрос.

Я нашел альтернативу, но также хотел, чтобы вы отказались от App Store: удалите всех наблюдателей из окна.

Если какая-то часть вашего приложения за пределами viewController нуждается в сообщениях об изменении ориентации, он может зарегистрироваться для них:

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

Окно, что неудивительно, регистрируется для таких уведомлений, а затем поворачивает контроллеры представления, если они принимают новую ориентацию. Это не удобно наблюдать за UIDeviceOrientationDidChangeNotification, поэтому должен быть эквивалент в частном порядке. Все, что вы можете сделать, - удалить каждое уведомление из окна:

[[NSNotificationCenter defaultCenter] removeObserver:[[self view] window]];

Восстановить это невозможно, если вы просто хотите временно отключить изменения ориентации. Мы также не можем сказать, просматривает ли окно какие-либо важные уведомления из других источников. Это тоже незавершенно - кнопка для переключения, и кнопка для съемки, перемещения и вращения самостоятельно.

Screenshot of iPad in landscape mode with camera UI still in portrait

Как вы можете исправить эту причуду? Вы можете отключить showsCameraControls на UIImagePicker и предоставить свой собственный cameraOverlayView кнопками камеры на нем. Или продолжить случайное удаление уведомлений, пройдя всю иерархию представлений (также материал отклонения), удаляя уведомления из всего:

- (void) removeAllNotificationsFromView:(UIView*) view;
{
    // This recurses through the view hierarchy removing all notifications for everything.
    // This is potentially destructive, and may result in rejection from the App Store.
    [[NSNotificationCenter defaultCenter] removeObserver:view];
    for (UIView *subview in [view subviews])
        [self removeAllNotificationsFromView:subview];
}

[self removeAllNotificationsFromView:imagePicker.view];

Я не рекомендую использовать это, но он дает некоторое интересное представление о том, как изменения и изменения ориентации обнаруживаются.

Ответ 3

Ни один из вышеперечисленных решений не работал у меня. Что сработало это (для iOS 7, на котором я его тестировал) -

  • Подкласс UIImagePickerController

  • Отменить метод shouldAutorotate и вернуть NO.

    -(BOOL)shouldAutorotate
    {
        return NO;
    }

Ответ 4

Добавить следующий код в ваш просмотр

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
     return NO;
}