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];
I managed to get this working by adding the following to my AVPlayerViewController in IB:
- An overlay view with a button inside it
- Add constraints to center the button in the overlay view
- Created an IBOutlet to the view (I called it 'overlay')
- Created an action from the button to AVPlayerViewController that prints something so that we can see that tapping the button is working
- 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
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!