Принудительная ориентация ландшафта на полноэкранном MPMoviePlayerController предотвращает правильное вращение при выходе из полноэкранного режима

У меня есть приложение для iPhone (iOS6 +), которое поддерживает все ориентации интерфейса. Тем не менее, только поддержка ландшафта должна поддерживаться, когда MPMoviePlayerController воспроизводит полноэкранный режим видео.

Я нашел следующее решение в Qaru и работает.

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];

...

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if (self.landscapeOnlyOrientation) {
        return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
    }
    return UIInterfaceOrientationMaskAll;
}

- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
    self.landscapeOnlyOrientation = YES;
}

- (void)moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
    self.landscapeOnlyOrientation = NO;
}

Однако сохраняется раздражающая проблема, а именно: если видео выходит из полноэкранного режима в портретной ориентации (после воспроизведения в вынужденном ландшафте), основной вид не поворачивается назад. Мне нужно вручную повернуть устройство в альбомную и обратно в портрет, чтобы инициировать обновление ориентации. Есть ли способ, с помощью которого я могу запускать этот вид обновления программно?

Следующий набор скриншотов должен иллюстрировать, что я имею в виду:

enter image description hereenter image description hereenter image description here

NB: По разным причинам использование MPMoviePlayerViewController невозможно.

Ответы

Ответ 1

Привет всем, у меня была такая же проблема, я ее разрешил -

Вот мой полный код....

Вам нужно сначала изменить appdelegate:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[[NowPlaying sharedManager] playerViewController] allowRotation])//Place your condition here
{
    return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}

Регистрация Уведомления для полноэкранного управления:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:)
                                             name:MPMoviePlayerWillEnterFullscreenNotification
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:)
                                             name:MPMoviePlayerWillExitFullscreenNotification
                                           object:nil];

Затем добавьте строку кода в контроллер плеера:

- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^
               {
                   self.allowRotation = YES;
               });
}



- (void)moviePlayerWillExitFullscreenNotification:(NSNotification *)notification
{
self.allowRotation = NO;
[self.moviePlayerController setControlStyle:MPMovieControlStyleNone];

dispatch_async(dispatch_get_main_queue(), ^
               {

                   //Managing GUI in pause condition
                       if (self.currentContent.contentType == TypeVideo && self.moviePlayerController.playbackState == MPMoviePlaybackStatePaused)
                   {
                       [self.moviePlayerController pause];
                       if (self.playButton.selected)
                           self.playButton.selected = NO;
                   }
                   self.view.transform = CGAffineTransformMakeRotation(0);
                   [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
                   self.view.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
               });
}

Этот код проверен в iOS6 и iOS7. Спасибо:)

Пожалуйста, дайте мне знать, если есть какие-либо вопросы.....

Ответ 2

Вам необходимо подкласс и обеспечить ландшафт в качестве поддерживаемой ориентации интерфейса.

@interface MyMovieViewController : MPMoviePlayerViewController
@end

@implementation MyMovieViewController

- (BOOL)shouldAutorotate 
{
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations 
{
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}

@end

Ответ 3

Вы можете попытаться "принудительно" обновить ориентацию, чтобы система обрабатывала правильную ориентацию для вас:

- (void)forceOrientationRefresh
{
    // Force orientation refresh
    [self presentModalViewController:[UIViewController new]
                            animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

Это хак-иш, но он работает.

Ответ 4

Это может показаться сумасшедшим, но вы можете попытаться сохранить локальную последнюю ориентацию перед открытием контроллера просмотра видео, а затем с помощью application:supportedInterfaceOrientationsForWindow: вернуть сохраненную ориентацию и заставить контроллер вида оставаться на нем и не вращаться.

Ответ 5

Вы можете программно изменить свою ориентацию следующим образом

-(void)viewDidAppear:(BOOL)animated
{

     if(UIDeviceOrientationIsPortrait(self.interfaceOrientation)){
        if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
        {
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeLeft );

        }
    }

}

И не забудьте добавить #import <objc/message.h>

Ответ 6

Я думаю, вы можете принудительно зарегистрировать свой контроллер просмотра для ориентации устройства и метода ориентации view viewcontroller.

Ответ 7

Вы используете supportedIterfaceOrientationsForWindow, затем найдите: MPInlineVideoFullscreenViewController. Немного сложно найти правильный контроллер, но он работает.

Вот пример кода:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    if ([NSStringFromClass([self.window.rootViewController.presentedViewController.presentedViewController class]) isEqualToString:@"MPInlineVideoFullscreenViewController"]){
    return UIInterfaceOrientationMaskAllButUpsideDown;
}
    return UIInterfaceOrientationMaskLandscape;
}

Ответ 8

вам нужно добавить этот код для iOS7 он работает идеально и просто

-(NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

.... creating a player
MPMoviePlayerViewController *mp =[[MPMoviePlayerViewController alloc] initWithContentURL:url];
...make settings and present it
[self presentMoviePlayerViewControllerAnimated:mp];