如何修复AVPlayer的视图控制器层次结构?

5
我有一个iOS应用程序,只有一个播放器和登录功能。它应该按照以下方式工作:
  • 1)运行应用程序
  • 2)登录
  • 3)登录后视频直接开始播放
  • 4)如果您退出视频,则应询问是否要注销
  • 5)如果选择“否”,则应继续播放流
  • 6)如果选择“是”,则注销应用程序
  • 7)如果用户在不关闭应用程序的情况下再次登录,则应从步骤2-7重复。
然而,我的代码除了最后一步之外都可以正常工作。如果用户注销并重新登录, - 它开始播放流 但是当您点击完成按钮并尝试退出视频时,它无法正常工作。视频仍然全屏显示,并显示以下警告:
Warning: <AVPlayerViewController: 0x7f9fca08aa00> is trying to exit full screen, but is not in its view's window's view controller hierarchy. This results in undefined behavior. 

我对xcode ios和Objective-C非常陌生,以下是我的代码:

- (void)viewDidLoad {

    NSLog(@"ChannelListingViewController::viewDidLoad(): Called...");
    [super viewDidLoad];

    self.check=1;

    NSLog(@"ChannelListingViewController::viewDidLoad(): Exiting...");
}

-(void) playVideo
{
    self.channelURL = [TulixAppGlobalConfig getUserSubscribedPlanChannels];


    NSURL *url = [[NSURL alloc] initWithString:[self.channelURL[1] getChannelHlsStreamURL]];
    self.player = [AVPlayer playerWithURL:url];

    // create a player view controller
    [self presentViewController:controller animated:YES completion:nil];
    self.controller.player = self.player;
    [self.player play];

}
-(void) viewDidAppear:(BOOL)animated
{

    self.controller = [[AVPlayerViewController alloc] init];

    NSLog(@"ChannelListingViewController::viewDidAppear(): Called...");
    if(self.check==0)
    {
        NSLog(@" 0 checkvalue: %i",check);
        [self showLogoutConfirmationDialog];
    }
    else{
        self.check =0;
        NSLog(@" 1 checkvalue: %i",check);
        [self playVideo];

    }

    [self spawnKeepAliveThread];
    NSLog(@"ChannelListingViewController::viewDidAppear(): Exiting...");
}

-(void) showLogoutConfirmationDialog
{
    void (^ptrFuncCompletionBlock)(void) = ^(void) {     NSLog(@"ChannelListingViewController::showLogoutConfirmationDialog():GENERIC CALL BACK...");
    [self attemptToLogoutUser];
};
NSLog(@"ChannelListingViewController::showLogoutConfirmationDialog(): Called...");

UIAlertAction* alertActionYes = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault
                                                         handler:^(UIAlertAction * action) {
                                                             //Do Some action here
                                                             NSLog(@"ChannelListingViewController::showLogoutConfirmationDialog:: Called for YES...");
                                                             self.check = 1;
                                                             NSLog(@" yes checkvalue: %i",check);
                                                             [self.activeAlterController dismissViewControllerAnimated:NO completion:ptrFuncCompletionBlock];
                                                             [self attemptToLogoutUser];
                                                         }];
UIAlertAction* alertActionNo = [UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleCancel
                                                          handler:^(UIAlertAction * action) {
                                                              NSLog(@"ChannelListingViewController::showLogoutConfirmationDialog:: Called for NO...");
                                                              [self playVideo];

                                                          }];

NSMutableArray* arrayAlertActions = [NSMutableArray arrayWithObjects:alertActionYes, alertActionNo, nil];
self.activeAlterController = [HelperUtility showMultiButtonDialogHavingTitle:@"Logout" withMessage:@"Are you sure you want to log out?" andAlertActions:arrayAlertActions];

[self presentViewController:self.activeAlterController animated:YES completion:nil];

NSLog(@"ChannelListingViewController::showLogoutConfirmationDialog(): Exit ");

我真的不明白为什么在注销后它不起作用,需要帮助。


问题在于播放器上的所有其他按钮都可以正常工作。当我点击“完成”(退出)按钮时,它会暂停流并显示上述警告。 - C.Aglar
友情提醒:如果您因为功能有限而愿意将应用提交到应用商店进行审核,那么您的应用很可能无法通过审核。 - Mosbah
@Mosbah,你所说的“有限功能”是什么意思? - C.Aglar
通常,此错误表示您正在在视图层次结构中呈现全屏控制器,但该控制器无法访问“全屏”模式。基本情况是在导航控制器内推送的控制器中进行呈现。需要由导航控制器来全屏呈现。您很可能遇到了类似的情况,即从错误的位置进行呈现。 - Peter Pajchl
1个回答

0
你只需要将你的AVPlayer控制器与窗口视图相关联。不要仅仅呈现AVController,还需添加以下代码:
Objective C-
[self.view.window.rootViewController presentViewController:controller animated:YES completion:nil];
Swift 5 -
view.window.rootViewController?.present(controller, animated: true)

1
你好,我遇到了同样的问题,我尝试了上面的方法,但仍然存在相同的问题。我的应用程序中有一个导航控制器和多个屏幕。在导航层次结构中的一个视图控制器中有一个按钮,可以在全屏模式下播放视频,但当我退出全屏模式时,它会将我发送回导航控制器的第一个视图,有什么帮助吗?此外,视频播放的视图是一个滚动视图,我不确定这是否有所不同。 - shant_01
@shant_01 我也遇到了同样的问题。你找到任何解决方案了吗? - user12208004
相同的问题。在导航堆栈中弹回一个视图控制器。 - zumzum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接