How do I intercept tapping of the done button in AVPlayerViewController?
ios, ios8, objective-c, xcode6
Solution
The fact that Apple provides no built-in way to handle the Done button is disappointing.
I didn't feel like inheriting from AVPlayerViewController, because it isn't supported by Apple and will probably open up a can of worms in one of the next iOS updates.
My workaround is to have a timer fire every 200 msec and check for the following condition:
if (playerVC.player.rate == 0 &&
(playerVC.isBeingDismissed || playerVC.nextResponder == nil)) {
// Handle user Done button click and invalidate timer
}
The player's `rate` property of 0 indicates that the video is no longer playing. And if the view controller is being dismissed or already dismissed, we can safely assume that the user clicked the Done button.
Problem
I created an `AVPlayerViewController` and an attached `AVPlayer` in the `viewDidAppear` method of a custom `UIViewController`. However, when I press the "Done" button my custom view controller is dismissed automatically. I would like to intercept this action in order to use my own unwind Segue, but I'm not sure how to do this. I've found examples for `MPMoviePlayerViewController` but not `AVPlayerViewController`. The code I found for `MPMoviePlayerViewController` is below: ``` - (void)playVideo:(NSString *)aVideoUrl { // Initialize the movie player view controller with a video URL string MPMoviePlayerViewController *playerVC = [[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:aVideoUrl]] autorelease]; // Remove the movie player view controller from the "playback did finish" notification observers [[NSNotificationCenter defaultCenter] removeObserver:playerVC name:MPMoviePlayerPlaybackDidFinishNotification object:playerVC.moviePlayer]; // Register this class as an observer instead [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:playerVC.moviePlayer]; // Set the modal transition style of your choice playerVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; // Present the movie player view controller [self presentModalViewController:playerVC animated:YES]; // Start playback [playerVC.moviePlayer prepareToPlay]; [playerVC.moviePlayer play]; } - (void)movieFinishedCallback:(NSNotification *)aNotification { // Obtain the reason why the movie playback finished NSNumber *finishReason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; // Dismiss the view controller ONLY when the reason is not "playback ended" if ([finishReason intValue] != MPMovieFinishReasonPlaybackEnded) { MPMoviePlayerController *moviePlayer = [aNotification object]; // Remove this class from the observers [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer]; // Dismiss the view controller [self dismissModalViewControllerAnimated:YES]; } } ``` I asked Apple about this problem and they've replied as follows: Thank you for contacting Apple Developer Technical Support (DTS). Our engineers have reviewed your request and have concluded that there is no supported way to achieve the desired functionality given the currently shipping system configurations.