How to make a AVPlayerViewController go to fullscreen programmatically? How to make a AVPlayerViewController go to fullscreen programmatically? ios ios

How to make a AVPlayerViewController go to fullscreen programmatically?


AVPlayerViewController is a subclass of UIViewController, so it is presentable like any other view controller subclass. Are you able to use presentViewController:animated:completion?

self.avPlayerController.modalPresentationStyle = UIModalPresentationOverFullScreen;[self presentViewController:self.avPlayerController animated:YES completion:nil];

This then shows the "Done" button in the top left-hand corner.


Updated for iOS 11

There is no supported way to programmatically go fullscreen with AVPlayerViewController (a bit of an oversight in my opinion).

However, AVPlayerViewController does contain a private method that does exactly that. You'll have to decide for yourself whether you'd want to use it or not given you're not supposed to call private methods.

AVPlayerViewController+Fullscreen.h

#import <AVKit/AVKit.h>@interface AVPlayerViewController (Fullscreen)-(void)goFullscreen;@end

AVPlayerViewController+Fullscreen.m

#import "AVPlayerViewController+Fullscreen.h"@implementation AVPlayerViewController (Fullscreen)-(void)goFullscreen {    NSString *selectorForFullscreen = @"transitionToFullScreenViewControllerAnimated:completionHandler:";    if (@available(iOS 11.3, *)) {        selectorForFullscreen = @"transitionToFullScreenAnimated:interactive:completionHandler:";    } else if (@available(iOS 11.0, *)) {        selectorForFullscreen = @"transitionToFullScreenAnimated:completionHandler:";    }    SEL fsSelector = NSSelectorFromString([@"_" stringByAppendingString:selectorForFullscreen]);    if ([self respondsToSelector:fsSelector]) {        NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:fsSelector]];        [inv setSelector:fsSelector];        [inv setTarget:self];        NSInteger index = 2; //arguments 0 and 1 are self and _cmd respectively, automatically set        BOOL animated = YES;        [inv setArgument:&(animated) atIndex:index];        index++;        if (@available(iOS 11.3, *)) {            BOOL interactive = YES;            [inv setArgument:&(interactive) atIndex:index]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation            index++;        }        id completionBlock = nil;        [inv setArgument:&(completionBlock) atIndex:index];        [inv invoke];    }}@end


In iOS11 there are 2 new properties for AVPlayerViewController: entersFullScreenWhenPlaybackBegins and exitsFullScreenWhenPlaybackEnds. You can enable full screen mode right after playback begins and disable it when playback ends with these properties. If you need to enable fullscreen mode after some delay you can use private API methods as ToddH mentioned in his answer. However in iOS11 _transitionToFullScreenViewControllerAnimated:completionHandler: method is not available anymore, there is the same method called _transitionToFullScreenAnimated:completionHandler:. The second method accepts the same arguments as the first one.

I can show an example how to use it. First of all you need to create AVPlayerViewController instance in your UIViewController:

private let playerController : AVPlayerViewController = {    if let urlForPlayer = URL(string: "your_video_url") {        $0.player = AVPlayer(url: urlForPlayer)    }    return $0} (AVPlayerViewController())

Then you need to setup view for AVPlayerViewController and add it to your current controller view. Function setupAVplayerController can do it for you:

private func setupAVplayerController() {    self.addChildViewController(self.playerController)    self.playerController.view.frame = CGRect(x: 0.0, y: 0.0, width: 200.0, height: 200.0)    self.view.addSubview(self.playerController.view)    self.playerController.didMove(toParentViewController: self)}

Function enterFullscreen forces full screen mode for AVPlayerViewController:

private func enterFullscreen(playerViewController:AVPlayerViewController) {    let selectorName : String = {        if #available(iOS 11, *) {            return "_transitionToFullScreenAnimated:completionHandler:"        } else {            return "_transitionToFullScreenViewControllerAnimated:completionHandler:"        }    }()    let selectorToForceFullScreenMode = NSSelectorFromString(selectorName)    if playerViewController.responds(to: selectorToForceFullScreenMode) {            playerViewController.perform(selectorToForceFullScreenMode, with: true, with: nil)    }}

And now you need to call all these functions where you need it, for example in viewDidAppear:

override func viewDidAppear(_ animated: Bool) {    super.viewDidAppear(animated)    //Your code    self.setupAVplayerController()    self.playerController.player?.play()    DispatchQueue.main.asyncAfter(deadline: .now() + 10) {        self.enterFullscreen(playerViewController:self.playerController)    }}

Don't forget that this solution based on private API calls that is not recommended to use.