Custom button in AVPlayerViewController.ContentOve

2019-05-25 02:52发布

问题:

I need to add a custom button to the AVPlayerViewController that will appear in both fullscreen and non-fullscreen for an app running iOS 8.

Adding a button to the AVPlayerViewController.view or the containing view will work for non-fullscreen but when the player switches to fullscreen the button is no longer visible. I have found that if I add a button to the AVPlayerViewController.ContentOverlayView then it appears in fullscreen and non-fullscreen, but then it doesn't appear that the ContentOverlayView responds to any touches so the button cannot be clicked. Does anyone know of a different place to add the button or a way to make the ContentOverlayView respond to touches?

Example Code

AVPlayerViewController *playerView = [[AVPlayerViewController alloc] init];
playerView.player = [AVPlayer playerWithURL:movieURL];
CGRect viewInsetRect = CGRectInset ([self.view bounds],
                                    kMovieViewOffsetX,
                                    kMovieViewOffsetY );
/* Inset the movie frame in the parent view frame. */
[[playerView view] setFrame:viewInsetRect];
[self.view addSubview: [playerView view]];

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor yellowColor];
btn.frame = CGRectMake(50, 50, 200, 75);
[btn addTarget:self action:@selector(didSelectButton:) forControlEvents:UIControlEventTouchUpInside];
[btn setUserInteractionEnabled:YES];
[btn setEnabled:YES];

[playerView.contentOverlayView addSubview:btn];

回答1:

I managed to get this working by adding the following to my AVPlayerViewController in IB:

  1. An overlay view with a button inside it
  2. Add constraints to center the button in the overlay view
  3. Created an IBOutlet to the view (I called it 'overlay')
  4. Created an action from the button to AVPlayerViewController that prints something so that we can see that tapping the button is working
  5. Dragged the overlay view out of the view hierarchy and onto the top bar of the view controller (appears as a view icon in top bar of the view controller along with the exit icon etc)

and then in the code for the AVPlayerViewController:

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(self.overlay)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        self.overlay.frame = self.view.bounds
    }

    @IBAction func playBtnTapped(sender: AnyObject) {
        println("PlayBtnTapped")
    }

The button is now centered in fullscreen/normal viewing and the button works



回答2:

I had the same predicament just now.

Instead of:

[playerView.contentOverlayView addSubview:btn];

use (after you add the playerView)

[self.view addSubview:btn];

This will add the button in the minimised player.

Now for the fullscreen I didn't found any other reliable method of checking if the player went fullscreen or back, so here is a a solution:

self.windowChecker = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkIfFullscreen) userInfo:nil repeats:YES];

and this:

-(void)checkIfFullscreen{
    NSLog(@"videoBounds\n %f %f ", self.avVideoPlayer.contentOverlayView.frame.size.width,self.avVideoPlayer.contentOverlayView.frame.size.height);

    if ([self playerIsFullscreen]) { // check the frame on this
        for(UIWindow* tempWindow in [[UIApplication sharedApplication]windows]){
            for(UIView* tempView in [tempWindow subviews]){

                if ([[tempView description] rangeOfString:@"UIInputSetContainerView"].location != NSNotFound){
                    UIButton *testB = [[UIButton alloc] initWithFrame: CGRectMake(20, 20, 400, 400)];
                    testB.backgroundColor = [UIColor redColor];
                    [testB addTarget:self action:@selector(buttonTouch) forControlEvents:UIControlEventTouchDown];
                    [tempView addSubview:testB];

                    break;
                }
            }
        }
    }
}

I know this is a not a nice way to do it, but it is the only way I managed to add some custom UI that also receives touch events on the player.

Cheers!