How do I intercept tapping of the done button in A

2019-02-11 17:29发布

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.

8条回答
冷血范
2楼-- · 2019-02-11 18:23

If you have a view controller A that presents a AVPlayerViewController, you could probably check in viewDidAppear/viewWillAppear inside VC A. Whenever those are called, at least we would know that the AVPlayerViewController is no longer shown and thus should not be playing.

查看更多
趁早两清
3楼-- · 2019-02-11 18:26

One way is to add additional action to the existing "Done" button on the AVPlayerViewController by searching the respective UIButton inside the subviews of AVPlayerViewController. Once the button is found, add a custom action using addTarget:action:forControlEvents:

At least this works for me.

- (UIButton*)findButtonOnView:(UIView*)view withText:(NSString*)text
{
    __block UIButton *retButton = nil;

    [view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if([obj isKindOfClass:[UIButton class]]) {
            UIButton *button = (UIButton*)obj;
            if([button.titleLabel.text isEqualToString:text]) {
                retButton = button;
                *stop = YES;
            }
        }
        else if([obj isKindOfClass:[UIView class]]) {
            retButton = [self findButtonOnView:obj withText:text];

            if(retButton) {
                *stop = YES;
            }
        }
    }];

    return retButton;
}

- (void)showPlayer:(AVPlayer*)player
{
    AVPlayerViewController *vc = [[AVPlayerViewController alloc] init];
    vc.player = player;

    [self presentViewController:vc animated:NO completion:^{
        UIButton *doneButton = [self findButtonOnView:vc.view withText:@"Done"];
        [doneButton addTarget:self action:@selector(doneAction:) forControlEvents:UIControlEventTouchUpInside];
        [vc.player play];
    }];

}

- (void)doneAction:(UIButton*)button
{
    // perform any action required here
}
查看更多
登录 后发表回答