简体   繁体   中英

Presenting a View Controller after a UIPopoverController is dismissed

I am having some difficulty presenting a full screen View Controller (specifically, an MPMoviePlayerViewController ) immediately after dismissing a UIPopoverController . Essentially, I have a race condition and I'm not sure if there's an accepted best practice to correct it. Here is the code I started with:

   [[self searchPopoverController] dismissPopoverAnimated:YES];

   MPMoviePlayerViewController *player = [[MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:[video videoURL]];
   [[player moviePlayer] setFullscreen:YES animated:YES];
   [self presentMoviePlayerViewControllerAnimated:player];

The problem is that the popover doesn't actually dismiss before the next lines of code are executed, resulting (as expected) in an "Attempt to present [a view controller] while a presentation is in progress" warning. Somewhat humorously, the video does start playing (you can hear the audio), but the view controller is not presented so you cannot see the video.

I've tried fixing this in several ways. The only reliable solution I have found is ugly and not a guaranteed fix:

   [[self searchPopoverController] dismissPopoverAnimated:YES];

   dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
   dispatch_after(start, dispatch_get_main_queue(), ^(void){
      MPMoviePlayerViewController *player = [[MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:[video videoURL]];
      [[player moviePlayer] setFullscreen:YES animated:YES];
      [self presentMoviePlayerViewControllerAnimated:player];
   });

Since UIPopoverController does not inherit from UIViewController , I do not believe there is any method for dismissing the popover that includes a completion-handling block. I've tried using NSInvocationOperation and NSOperationQueue , with no success, for example:

   NSInvocationOperation *invokedOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(playVideo:) object:video];
   [[NSOperationQueue mainQueue] addOperation:invokedOperation];

There are lots of existing questions that touch on this issue, but most seem to revolve around dismissing a UIViewController or subclass, for which dismissViewControllerAnimated:completion: is an obvious solution.

You should use the popover delegate method popoverControllerDidDismissPopover

This will notify you once the pop over has fully been dismissed. https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverControllerDelegate_protocol/index.html#//apple_ref/occ/intfm/UIPopoverControllerDelegate/popoverControllerDidDismissPopover :

为什么不实现UIPopoverControllerDelegate协议并将您的控制器添加为委托,那么您可以将第二个viewController从

-(void)popoverControllerDidDismissPopover:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM