5

I want to play video in landscape mode in fullscreen. And my application is lock in portrait mode. How to implement this. Please help me. Thanks in advance

Monika Patel
  • 2,287
  • 3
  • 20
  • 45

5 Answers5

10

Simplest solution in swift 3 Add this to your app delegate:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    if window == self.window {
        return .portrait
    } else {
        return .allButUpsideDown
    }
}
Eyzuky
  • 1,843
  • 2
  • 22
  • 45
  • 2
    Man, you rock! Simple and elegant solution. You saved my day. thank you. – rmvz3 Apr 26 '17 at 23:21
  • This is awesome! I'm getting a strange bug though. If the user clicks done on the the video while still in landscape the navigation bar gets shifted up 30 pixels or so for all view controllers. Any ideas on a fix for this? – Groovietunes May 02 '17 at 06:19
  • 1
    I've posted my answer [above (Accepted :P)](https://stackoverflow.com/a/36760674/3308174), but now i use new approach like yours but in ObjC. – Pratik Jamariya Jun 03 '17 at 14:27
  • @Groovietunes i've had same issue like yours in one of my app, can you tell me how do you dismiss/remove your player window? i can help you on that – Pratik Jamariya Jun 03 '17 at 14:30
  • @PratikJamariya it's dismissed manually by clicking the done button in the top left corner. I'm using a web view with an embedded youtube video – Groovietunes Jun 10 '17 at 00:13
  • Hey @Groovietunes! i guess it was because of status bar wasn't being set properly when the window(player window i mean here) was dismissed(hidden), so i did few tricks with the window. when i dismiss the window i set its rootviewcontroller to nil and hide the window `window.rootViewController = nil;` `[window setHidden:YES];` it'll force keyWindow to set status bar and navigation bar wont lift up. Correct me if i'm wrong somewhere, i've working app with this issue solved. – Pratik Jamariya Jun 10 '17 at 05:39
  • Clever solution! Is there any chance that when `window != self.window`, it's not a video playing window, but something else? – JonSlowCN Feb 21 '19 at 08:36
  • @JonSlowCN everything is possible, sure. But your AppDelegate has only 1 property of self.window, which hopefully is your app. Some apps might use other windows, you should check your view hierarchy and see if you have other Windows in different scenarios – Eyzuky Feb 21 '19 at 08:39
  • 1
    @Eyzuky Good point. The basic idea is brilliant. Detailed logic to check whether it's the right window may vary from different Apps. Thank you! – JonSlowCN Feb 21 '19 at 08:44
2

I've done this in on of my app. To do this you need to check that is your viewcontroller that where you want to play a video.

  • The first thing you have to do is check Device Orientation to Portrait,Landscape left, Landscape right in your project target

  • In your AppDelegate do the below code

    -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    
        UIStoryboard *mainStoryboard;
        if (IS_IPHONE) {
            mainStoryboard= [UIStoryboard storyboardWithName:@"Main" bundle: nil];
        }
        else{
           mainStoryboard= [UIStoryboard storyboardWithName:@"Main_iPad" bundle: nil];
        }
    
        ViewControllerThatPlaysVideo *currentViewController=    ViewControllerThatPlaysVideo*)[mainStoryboard     instantiateViewControllerWithIdentifier:@"postDetailView"];
        if(navigationController.visibleViewController isKindOfClass:    [ViewControllerThatPlaysVideo class]]){
           if([currentViewController playerState])
                return UIInterfaceOrientationMaskLandscape|UIInterfaceOrientationMaskPortrait;
           return UIInterfaceOrientationMaskPortrait;
        }
        return UIInterfaceOrientationMaskPortrait;
    }
    
Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Pratik Jamariya
  • 810
  • 1
  • 10
  • 35
1
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

Just call it in - viewDidAppear: of the presented view controller.

Another way :

First, you have to understand that in order to open even just one view out of over 100 in landscape, your app should allow both landscape and portrait interface orientations. It is the case by default, but you can check it in your target's settings, General tab, Deployment Info section

Then, because you allowed both landscape and portrait for the entire app, you will have to tell every portrait-only UIViewController that it should not autorotate, adding this method's implementation:-

- (BOOL)shouldAutorotate {
    return NO;
}

Finally, for your specific landscape-only controller, and because you said you are presenting it modally, you can just implement these methods:-

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeLeft; // or Right of course
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Hope this will help :)

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • My view rotating perfectly but video is not play in landscape. Plz check my screenshot. @Lion – Monika Patel Apr 21 '16 at 06:17
  • that viewcontroller is not rotating in landscape according to your screenshot. so try my answer. allow `autorotating` to `videoPlayerViewController` and set orientation landscapeleft for that videoplayerviewcontroller – Ketan Parmar Apr 21 '16 at 06:31
1

After staring at this page for almost an entire day, I finally figured out a working time saving solution for all,

Go to the project navigator, select your project and in General select just potrait in device orientation.

Also make sure that you're using a modal segue to show the landscapeController.

Now add this in your controller where in you want the landscape mode.

override func viewWillAppear(_ animated: Bool) {

    super.viewWillAppear(true)
}

override var shouldAutorotate: Bool {

    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {

    return .landscapeRight
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {

    return .landscapeRight
}

And that's it folks.

Ameya Vichare
  • 1,119
  • 1
  • 10
  • 22
0

add this file to your project

import UIKit

final class DeviceOrientation {
    
    static let shared: DeviceOrientation = DeviceOrientation()
    
    // MARK: - Private methods
    
    @available(iOS 13.0, *)
    private var windowScene: UIWindowScene? {
        return UIApplication.shared.connectedScenes.first as? UIWindowScene
    }
    
    // MARK: - Public methods
    
    func set(orientation: UIInterfaceOrientationMask) {
        if #available(iOS 16.0, *) {
            windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: orientation))
        } else {
            UIDevice.current.setValue(orientation.toUIInterfaceOrientation.rawValue, forKey: "orientation")
        }
    }
    
    var isLandscape: Bool {
        if #available(iOS 16.0, *) {
            return windowScene?.interfaceOrientation.isLandscape ?? false
        }
        return UIDevice.current.orientation.isLandscape
    }
    
    var isPortrait: Bool {
        if #available(iOS 16.0, *) {
            return windowScene?.interfaceOrientation.isPortrait ?? false
        }
        return UIDevice.current.orientation.isPortrait
    }
    
    var isFlat: Bool {
        if #available(iOS 16.0, *) {
            return false
        }
        return UIDevice.current.orientation.isFlat
    }
}

extension UIInterfaceOrientationMask {
    var toUIInterfaceOrientation: UIInterfaceOrientation {
        switch self {
        case .portrait:
            return UIInterfaceOrientation.portrait
        case .portraitUpsideDown:
            return UIInterfaceOrientation.portraitUpsideDown
        case .landscapeRight:
            return UIInterfaceOrientation.landscapeRight
        case .landscapeLeft:
            return UIInterfaceOrientation.landscapeLeft
        default:
            return UIInterfaceOrientation.unknown
        }
    }
}

how we can use it?

DeviceOrientation.shared.set(orientation: .landscapeRight) 

It'll work like a charm

Ahmed Rajib
  • 67
  • 1
  • 4