MPMoviePlayerViewController Enable Landscape Mode - ios

I am adding an MPMoviePlayerViewController to my app like this:
MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];;
[self presentMoviePlayerViewControllerAnimated:vc];
Everything is working but I can't enable landscape mode. I want my whole app except the actual MPMoviePlayerViewController to be portrait. I searched on google but all the solutions require having the rest of the app also in landscape.I need my app to stay in Portrait except in the MPMoviePlayerViewController.
Thanks in advance!
EDIT:
Using #matt answer I added landscape to my Device Orientation:
Next I went to my First View Controller(Not the MPMoviePlayerViewController) and added:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
However the app still let's the Main Menu go to Landscape mode.

Actually there is a way to just make Movie Player landscape without affecting portrait view of rest of screens.
#define degreesToRadian(x) (M_PI * (x) / 180.0)
MPMoviePlayerViewController *moviePlayerVC = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:#"http://someurl.com"]];
moviePlayerVC.view.transform = CGAffineTransformIdentity;
moviePlayerVC.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
[self presentViewController:moviePlayerVC animated:NO completion:NULL];
Make sure you are using MPMoviePlayerViewController and not MPMoviePlayerController, else it won't work.

The problem is that MPMoviePlayerViewController is not your class so you have no control over its response to supportedInterfaceOrientations, which is what you would use to dictate the orientation of the presented view if this were your own view controller class. So you must make it your own view controller class. You will have to create your own MPMoviePlayerViewController subclass so that you can override supportedInterfaceOrientations and express what orientation you want (i.e. landscape). Create and present an instance of that subclass, not the built-in superclass.

For Xcode 6.4, Swift 1.2 edited #Chandresh Panchasara answer a bit.
let movieC = MPMoviePlayerViewController()
movieC.moviePlayer.contentURL = self.movieURL
movieC.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
movieC.view.transform = CGAffineTransformIdentity;
movieC.view.transform = CGAffineTransformMakeRotation(CGFloat((M_PI * (90.0) / 180.0)));
self.view.window?.rootViewController?.addChildViewController(self)
self.presentMoviePlayerViewControllerAnimated(movieC)

Thanks for you answers it helped me.
For those who want it for Swift 4 here the solution:
playerVC.view.transform = CGAffineTransform.identity
playerVC.view.transform = CGAffineTransform.init(rotationAngle: degreesToRadian(90.0))
present(strongPlayerVC, animated: true)
Here the function degreesToRadian:
func degreesToRadian(_ degrees: CGFloat) -> CGFloat {
return .pi * degrees / 180.0
}
Thanks and good luck!

The best way so far is to implement this AppDelegate function and check if the rootViewController has a child of type AVPlayerViewController then you return [.portrait, .landscapeLeft, .landscapeRight] and else .portrait.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if let _ = UIApplication.shared.keyWindow?.rootViewController?.childViewControllers.first as? AVPlayerViewController {
return [.portrait, .landscapeLeft, .landscapeRight]
}
return .portrait
}
You should check on the keyWindow of UIApplication because apple presents this viewController in a another UIWindow so if you try to do that check on the window that is declared in the AppDelegate this won't work so be careful.

Related

Force View Controller Orientation in iOS 9

I am working on a photography app that allow photos to be taken in portrait or landscape. Due to the requirements of the project, I cannot let the device orientation autorotate, but rotation does need to be supported.
When using the following orientation methods:
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if self.orientation == .Landscape {
return UIInterfaceOrientationMask.LandscapeRight
} else {
return UIInterfaceOrientationMask.Portrait
}
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
if self.orientation == .Landscape {
return UIInterfaceOrientation.LandscapeRight
} else {
return UIInterfaceOrientation.Portrait
}
}
I am able to set rotation correctly at launch. By changing the orientation value and calling UIViewController.attemptRotationToDeviceOrientation() I am able to support rotation to the new desired interface. However, this rotation only occurs when the user actually moves their device. I need it to happen automatically.
I am able to call: UIDevice.currentDevice().setValue(targetOrientation.rawValue, forKey: "orientation") to force the change, but that causes other side effects because UIDevice.currentDevice().orientation only returns the setValue from that point on. (and it's extremely dirty)
Is there something I'm missing? I've looked into closing and launching a new view controller, but that has other issues such as a constant UI glitch when dismissing and immediately presenting a new view controller.
EDIT:
The following methods did not work for me:
Trick preferredInterfaceOrientationForPresentation to fire on viewController change
Forcing UIInterfaceOrientation changes on iPhone
EDIT 2:
Thoughts on potential solutions:
set orientation directly (with setValue) and deal with all the side effects this presents on iOS 9 (not acceptable)
I can use the current solution and indicate that the user needs to rotate the device. Once the device has been physically rotated, the UI rotates and then locks in place correctly. (poor UI)
I can find a solution that forces the refresh of orientation and rotates without physical action. (what I'm asking about, and looking for)
Do it all by hand. I can lock the interface in portrait or landscape, and manually rotate and resize the container view. This is 'dirty' because it forgoes all of the size class autolayout features and causes much heavier code. I am trying to avoid this.
I was able to find a solution with the assistance of this answer: Programmatic interface orientation change not working for iOS
My base orientation logic is as follows:
// Local variable to tracking allowed orientation. I have specific landscape and
// portrait targets and did not want to remember which I was supporting
enum MyOrientations {
case Landscape
case Portrait
}
var orientation: MyOrientations = .Landscape
// MARK: - Orientation Methods
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if self.orientation == .Landscape {
return UIInterfaceOrientationMask.LandscapeRight
} else {
return UIInterfaceOrientationMask.Portrait
}
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
if self.orientation == .Landscape {
return UIInterfaceOrientation.LandscapeRight
} else {
return UIInterfaceOrientation.Portrait
}
}
// Called on region and delegate setters
func refreshOrientation() {
if let newOrientation = self.delegate?.getOrientation() {
self.orientation = newOrientation
}
}
Then when I want to refresh the orientation, I do the following:
// Correct Orientation
let oldOrientation = self.orientation
self.refreshOrientation()
if self.orientation != oldOrientation {
dispatch_async(dispatch_get_main_queue(), {
self.orientationRefreshing = true
let vc = UIViewController()
UIViewController.attemptRotationToDeviceOrientation()
self.presentViewController(vc, animated: false, completion: nil)
UIView.animateWithDuration(0.3, animations: {
vc.dismissViewControllerAnimated(false, completion: nil)
})
})
}
This solution has the side effect of causing view[Will/Did]Appear and view[Will/Did]Disappear to fire all at once. I'm using the local orientationRefreshing variable to manage what aspects of those methods are called again.
I've encountered this exact problem in the past, myself. I was able to solve it using a simple work around (and GPUImage). My code is in Objective-C but i'm sure you'll have no problem translating it to Swift.
I began by setting the project's supported rotations to all that I hoped to support and then overriding the same UIViewController methods:
-(BOOL)shouldAutorotate {
return TRUE;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
Which allows the device to rotate but will persist in Portrait mode. Then began observing for Device rotations:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(adjustForRotation:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Then updated the UI if the device was in Portrait mode or landscape:
-(void)adjustForRotation:(NSNotification*)notification
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
{
// UPDATE UI
}
break;
case UIDeviceOrientationLandscapeRight:
{
// UPDATE UI
}
break;
default: // All other orientations - Portrait, Upside Down, Unknown
{
// UPDATE UI
}
break;
}
}
And finally, GPUImage rendered the image based on the device's orientation.
[_gpuImageStillCamera capturePhotoAsImageProcessedUpToFilter:last_f
withCompletionHandler:^(UIImage *processedImage, NSError *error) {
// Process the processedImage
}];
So I looked at the private headers of UIDevice, and it appears that there are two setters, and two property definitions, for orientation, which is currently baffling me. This is what I saw...
#property (nonatomic) int orientation;
#property (nonatomic, readonly) int orientation;
- (void)setOrientation:(int)arg1;
- (void)setOrientation:(int)arg1 animated:(BOOL)arg2;
So when I saw that you used setValue:forKey:, I wanted to see there was a synthesized setter and getter, and am honestly not 100% sure as to which one is being set, and which one is being acknowledged by the device... I attempted in a demo app to use setValue:forKey: to no avail, but used this trick from one of my past applications, and it did the trick right away :) I hope this helps
UIDevice.currentDevice().performSelector(Selector("setOrientation:"), withObject: UIInterfaceOrientation.Portrait.rawValue)

How to make a AVPlayerViewController go to fullscreen programmatically?

I'm trying to make a AVPlayerViewController go to full screen mode programmatically, coming from "embedded" mode, however this does not appear to be possible with the published API.
Is there a workaround that I'm missing? I'm interested in obtaining the same animation to the one that you get when the user presses the full screen button on the bottom right of the controls.
Using MPMoviePlayerController is not a viable alternative since I might have more than one video playing at a time.
Thanks.
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
UPDATE: Swift 4 version of ToddH's answer:
private func enterFullscreen(playerViewController: AVPlayerViewController) {
let selectorName: String = {
if #available(iOS 11.3, *) {
return "_transitionToFullScreenAnimated:interactive:completionHandler:"
} else 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)
}
}
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.
As a little iOS 14 update to ToddH's answer: the private API to call is enterFullScreenAnimated:completionHandler:. So here's an extension on AVPlayerViewController to enter full screen.
extension AVPlayerViewController {
func enterFullScreen(animated: Bool) {
perform(NSSelectorFromString("enterFullScreenAnimated:completionHandler:"), with: animated, with: nil)
}
func exitFullScreen(animated: Bool) {
perform(NSSelectorFromString("exitFullScreenAnimated:completionHandler:"), with: animated, with: nil)
}
}
This implementation doesn't offer a completion callback. If you pass a Swift closure to the completionHandler parameter, it crashes in the underlying Obj-C API. I haven't investigated how to pass the closure to make it work.
Swift 3 version for the answer of ToddH:
extension AVPlayerViewController {
func goFullScreen() {
let selector = NSSelectorFromString("_transitionToFullScreenViewControllerAnimated:completionHandler:")
if self.responds(to: selector) {
// first argument is animated (true for me), second is completion handler (nil in my case)
self.perform(selector, with: true, with: nil)
}
}
}
You can just set the videoGravity property of AVPlayerViewController.
if(fullscreen)
{
[self.avPlayerController
setVideoGravity:AVLayerVideoGravityResizeAspectFill];
}
else
{
[self.avPlayerController
setVideoGravity:AVLayerVideoGravityResizeAspect];
}
For an 'embedded' AVPlayerViewController instance, it is quite easy to programmatically have it start playback in full screen mode, and without hacking anything (calling private methods). You just need to set its entersFullScreenWhenPlaybackBegins property to true.
You need to add the controller as a child VC to the main VC, and that's basically it. In viewDidAppear(_:) you need to call play() method on the controller's player property - playback will be automatically started in fullscreen.
It's often best to check Apple sample code for these kind of tricky APIs; I think this one might be useful for a lot of AVPlayer use cases: Using AVKit in iOS.
I did not have the need to use any restricted code.
For this, I am assuming that you have added the AVPlayerViewController as a child view controller.
Then for that you will first have to remove the child view controller and then present it again as a fullscreen controller as well attach the AVPlayer view properly to it's parent view.
Here is how I did it. Please note that I am using a library called Easy Peasy for restoring the playerVC.view constraints - one can do that with proper constraints as well.
#objc func fullscreenButtonClicked() {
playerVC.willMove(toParentViewController: nil)
playerVC.view.removeFromSuperview()
playerVC.removeFromParentViewController()
self.present(self.playerVC, animated: false, completion: {
self.playerVC.view.easy.layout(Top(), Right(), Left(), Bottom())
})
}
Its pretty simple, just set
playerViewController.videoGravity = .resizeAspectFill
and it goes full screen:)

iOS: How to change Orientation of only one view controller in app?

I am facing problem in view orientation in my app.
Like
I have two view controller, VC1 and VC2
VC1 have fix landscape orientation.
VC2 have both
VC1 -> VC2 is fine. means when I go from VC1 to VC2, VC2 change its orientation in both landscape and portrait.
But when I comeback to VC1 from VC2(where VC2 in portrait mode), VC1 also is in portrait mode but I want VC1 is in landscape only irrespective of VC2 mode.
Please guys help me. Seeking solution from last 2 days.
Thanks in advance.
Refer below link for solution
http://swiftiostutorials.com/ios-orientations-landscape-orientation-one-view-controller/
In your VC1..
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
Hope it helps you...
First of all, write this in AppDelegate.m
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return (UIInterfaceOrientationMaskAll);
}
Then, For VC1, in which landscape orientation, write this:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}
For VC2, which have both, change masking to All.
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskAllButUpsideDown);
//OR return (UIInterfaceOrientationMaskAll);
}
1. Enable all orientation support for project.
For VC1 Add this line VC1Controller Class
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
For VC2 Add this in VC2Controller Class
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
basically the view-controller-based orientation support in an iOS app is a piece of cake – I did the code in Swift, but ObjC concept would be totally identical to this.
I have created a quick tutorial with UINavigationController but you can convert that to UITabBarController by keeping the concept but updating the environment slightly.
step-1
initially set the orientation support for your app like this:
step-2
create a simple UINavigationController-based storyboard like this:
NOTE: don't worry if it does not say initially OrientaionSupporterController (bonus point if you'd spot the consistent typo here!), I will cover that just in the very next step.
step-3
create a subset of the navigation-controller, like this:
import UIKit
// MARK: - Implementation
class OrientaionSupporterController: UINavigationController {
// MARK: - Active View Controller
private var activeViewController: UIViewController? {
get {
return self.presentedViewController ?? self.topViewController // for possible modal support
}
}
// MARK: - Orientations
override var shouldAutorotate: Bool {
get {
return self.activeViewController?.shouldAutorotate ?? true // yes, rotate it, please
}
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return self.activeViewController?.supportedInterfaceOrientations ?? .all // default is all possible orientations
}
}
then make sure the that becomes the base class in IB as well:
step-3
create the individual view-controllers with custom orientation support, like e.g. with only portrait and landscape-left support:
import UIKit
// MARK: - Implementation
class ViewController: UIViewController {
// MARK: - Orientation
override var shouldAutorotate: Bool {
get {
return true
}
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return [.portrait, .landscapeLeft] // no one find that preactical but works flawlessly
}
}
NOTE: you can convert this tutorial anytime with UITabBarController, you just need to (obviously) create a subset of the tab-bar-controller and use the selectedViewController to get the currently visible one.
NOTE#2: obviously you can go much further on this way and you can nest the customised navigation-controllers in the view hierarchy, or if you have multiple UIWindow instances in the queue and override the supported orientations there as well for each individual windows (e.g. some support all four orientations, while some other windows does only landscape for e.g. video playback, etc...)

iOS7 viewController and MPMoviePlayerViewController Rotation

I try a lot of things, but I still can't rotate only 1 viewControllor in all my app.
I would like to show (or to rotate) in landscape only a vc with a MPMoviePlayerViewController.
Like the videos in Facebook app. The app is only in portrait but video could rotate.
After played the video, application return in portrait mode.
I'm able to ratate but after "done" videoplayer button clicked the view return in landscape mode.
How can I fix this?
Thank you very much.
Create new View controller for Playing videos
Click on Project then click on Target. In General category under Deployment Info enable All the rotations
Now open your Root view controller and Put following lines.give what orientation of your app
code:
-(BOOL)shouldAutorotate
{
return TRUE;
}
-(NSUInteger)supportedInterfaceOrientations
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
return UIInterfaceOrientationMaskPortrait;
}
else
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
}
4.Now if you used addsubview method to represent your other ViewController's views then no need to apply orintation methods to other controller. But If any vc you have used PresentController method then add orientation methods to that conroller
Create a new UIViewController that you will use for showing a video.
Create a MPMoviePlayerController property
#property (nonatomic, strong) MPMoviePlayerController* moviePlayerController;
Then in viewDidLoad, try this:
- (void)viewDidLoad
{
[super viewDidLoad];
_moviePlayerController = [[MPMoviePlayerController alloc] init];
_moviePlayerController.controlStyle = MPMovieControlStyleFullscreen;
_moviePlayerController.contentURL = [NSURL URLWithString:#"example.com"];
// Rotating the player to landscape position
_moviePlayerController.view.frame = CGRectMake(0.0f,
0.0f,
[UIScreen mainScreen].bounds.size.height,
[UIScreen mainScreen].bounds.size.width);
_moviePlayerController.view.transform = CGAffineTransformMakeRotation(M_PI_2);
_moviePlayerController.view.center = self.view.center;
UIView *playerView = _moviePlayerController.view;
[self.view insertSubview:playerView atIndex:0];
[_moviePlayerController prepareToPlay];
}
Hope it helps.

Set fullscreen mode in iOS programmatically

How to set an iOS app for iPad to fullscreen programmatically?
Are you talking about the status bar which is visible? In the info.plist for your app, you can add a new entry, UIStatusBarHidden and make sure its checked. This would ensure that the status bar is hidden. You also have to make sure that your views are able to handle the additional screen real estate also.
Nowadays (since IOS7) in order to do this you need to override a small tiny lily method of each UIViewController you want to do this
Swift
override func prefersStatusBarHidden() -> Bool {
return true;
}
Objective C
-(BOOL)prefersStatusBarHidden{
return YES;
}
Apple Doc:
Maybe you want this one:
[self setWantsFullScreenLayout:YES];
just add it at your viewController's init method.
Someone else may need it. ;)
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
(other animation modes are ...Fade and ...Slide.)
You need to override var rather func,
override var prefersStatusBarHidden: Bool {
return true
}

Resources