How to rotate a video embed in UIWebView (for iOS 7 only)?
Asked Answered
K

8

5

The app I'm working on is portrait oriented, but when a video is running (it is embed in a webview), I need to re-orient the video in landscape mode. How should I do that? I found a solution, which worked just fine until days ago :). I believe it's because iOS 7 updates, but I'm not sure. So, this is what I previously used, but it is not working anymore because window and class name are always nil.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{

id presentedViewController = [window.rootViewController presentedViewController];
NSString *className = presentedViewController ? NSStringFromClass([presentedViewController class]) : nil;

if (window && [className isEqualToString:@"MPInlineVideoFullscreenViewController"]) {
    return UIInterfaceOrientationMaskAll;
} else {
    return UIInterfaceOrientationMaskPortrait;
}
Kermitkermy answered 28/2, 2014 at 13:2 Comment(1)
possible duplicate of UIMoviePlayerControllerDidEnterFullscreenNotification not work in iOS8Tymbal
K
9

I found a solution by myself, finally! I implemented the following method in AppDelegate and it worked. My problem was that, at first, I didn't check the right view controller.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {

NSString *className = NSStringFromClass([window class]);
if ([((UINavigationController *)window.rootViewController) respondsToSelector:@selector(visibleViewController)]) {
    className = NSStringFromClass([((UINavigationController *)window.rootViewController).visibleViewController class]);
}

if ([className isEqualToString:@"MPFullscreenWindow"] || [className isEqualToString:@"MPInlineVideoFullscreenViewController"]) {
    return UIInterfaceOrientationMaskAll;
} else if  (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
    return UIInterfaceOrientationMaskLandscape;
} else {
    return UIInterfaceOrientationMaskPortrait;
} 
Kermitkermy answered 4/3, 2014 at 8:0 Comment(1)
Have you submitted an app to the store with this code in it? If so, did Apple accept it?Quash
M
1

Here's a solution that will allow rotation on any additional windows presented in the iPhone app (such as a vide player) but remain landscape in an iPad app. Place it in your app delegate.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {


if  (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
    return UIInterfaceOrientationMaskLandscape;
} else {

    if (window == self.window
        || ![window isMemberOfClass:[UIWindow class]]) {
        return UIInterfaceOrientationMaskPortrait;
    }

    if ([window isEqual:[[UIApplication sharedApplication] windows][1]]) {
        // Rotate the secondary window.
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }

    return UIInterfaceOrientationMaskPortrait;
}
Macmahon answered 20/11, 2014 at 18:43 Comment(0)
P
1

So I figured I'd share what my solution was. Actually branching off of the OP question, just modified it. Works for me on iOS 7 and 8.

My approach was different as I have a toggle switch in another view controller that enables portrait or landscape.

Anyways, here it is.

UPDATED:

Ok so the previous method broke the launch screen. Example: If you have your device in landscape, and launched but it's a portrait app, it will rotate, BUT, the window will get cut in half. Pain in the butt esp if you have some nice loading screens going on. Anyways, the replaced code below fixes that AND allows video rotation. Obviously not everybody will be using a rotation switch, just adjust accordingly.

//Allow video only rotation in portrait mode.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{

    //Switch for Rotation
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    BOOL switchOn = [userDefaults boolForKey:@"Rotation"];

    if (switchOn) {
        window.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
        [window setFrame:[[UIScreen mainScreen] bounds]]; //Add
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    else {
        id presentedViewController = [window.rootViewController presentedViewController];
        NSString *className = presentedViewController ? NSStringFromClass([presentedViewController class]) : nil;

        if ((window && [className isEqualToString:@"MPInlineVideoFullscreenViewController"]) ||
            [className isEqualToString:@"MPMoviePlayerViewController"] ||
            [className isEqualToString:@"AVFullScreenViewController"]) {

            window.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
            [window setFrame:[[UIScreen mainScreen] bounds]]; //Add
            [window makeKeyAndVisible];

            return UIInterfaceOrientationMaskAllButUpsideDown;
        }

        window.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
        [window setFrame:[[UIScreen mainScreen] bounds]]; //Add
        return UIInterfaceOrientationMaskPortrait;
    }

    self.window.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
    [self.window setFrame:[[UIScreen mainScreen] bounds]]; //Add
    [self.window makeKeyAndVisible];
}

UPDATED AGAIN:

So the previous edit I laid out had a weird flicker of the view below the movie player. This seems to have fixed that. Tested on 6+ device, and iOS 7/8 in the simulator.

Hope this helps somebody.

Pimiento answered 18/4, 2015 at 0:16 Comment(0)
M
1

Swift 3, I sorted out on this way (your info.plist / project settings can have ONYL the portrait orientation checked) :

// MARK: - Orientation

extension AppDelegate {
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

        // Let webView video to be rotated
        if window != self.window {
            return window?.rootViewController?.supportedInterfaceOrientations ?? .all;
        }

        // All other screens are portrait
        return .portrait;
    }

}
Mascia answered 3/3, 2017 at 15:50 Comment(0)
F
0

Try It....

-(BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return YES;
}

If you don't want your UIViewController to be able to rotate when the video isn't on the screen. Use this--

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(webView && webView.superView) return YES;
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
Flan answered 28/2, 2014 at 13:12 Comment(4)
Thank you for your answer. I tried your idea, but still not working. I used supportedInterfaceOrientations method to do that because the other one is deprecated. It is called, but no changes applied. I'm still searching for a solution...Kermitkermy
Yes, I found a solution, finally!Kermitkermy
actually I found another solution. I updated my post with it; maybe you're curious to check it :).Kermitkermy
I accepted my answer because it is the only one that worked for me, not because it is easier this way. As I said above, your solution did not work for me, even if I tried it. Keep up the good work! Thanks anyway! :)Kermitkermy
D
0

This is very similar to how I solved for iOS 7, but this doesn't work for iOS 8. MPFullscreenWindow is no longer returned and Xcode complains about breaking constraints.

Dolce answered 21/9, 2014 at 18:48 Comment(0)
S
0

My solution seems to be fairly general, and takes care of some weird behavior on iOS 7 where window sometimes passed in as nil.

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        return UIInterfaceOrientationMaskAll;
    }
    else
    {
        // when dismissing a view controller, the view controller being returned to isn't in control of the orientiation
        // (shouldAutorotate and supportedInterfaceOrientations seem to be called, but they aren't observed then,
        // rather only when the device is rotated after that view is fully showing)
        // instead, the result of this method only is what's observed
        // we could return different values depending on which view controller is frontmost, but currently it seems
        // good enough to call supportedInterfaceOrientations of the frontmost view controller and return that

        // on ios7, critical calls to this method are often passed window=nil, in that case use self.window instead
        UIViewController *frontViewController = window ? window.rootViewController : self.window.rootViewController;

        // special case only when transitioning to or from a presented view controller
        if (frontViewController.presentedViewController &&
            (frontViewController.presentedViewController.isBeingDismissed || frontViewController.presentedViewController.isBeingPresented))
        {
            if (frontViewController.presentedViewController && !frontViewController.presentedViewController.isBeingDismissed) {
                frontViewController = frontViewController.presentedViewController;
            }
            if ([frontViewController isKindOfClass:[UINavigationController class]]) {
                frontViewController = ((UINavigationController *)frontViewController).topViewController;
            }

            // return whatever the front view controller's supportedInterfaceOrientations returns, since it normally is ignored for some reason
            return [frontViewController supportedInterfaceOrientations];
        }
        else
        {
            // return this normally, this gets intersected with the result of the front view controller's supportedInterfaceOrientations
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
    }
}
Stolon answered 27/1, 2015 at 23:20 Comment(0)
M
0
=> Put below method inside your  AppDelegate class, it allow to play video in landscape mode even when device orientation is locked to portrait mode only:


- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)windowx
{
    if ([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]] ||
    [[self.window.rootViewController presentedViewController] isKindOfClass:NSClassFromString(@"MPInlineVideoFullscreenViewController")])
    {
        if ([self.window.rootViewController presentedViewController].isBeingDismissed)
        {
            return UIInterfaceOrientationMaskPortrait;
        }
        else
        {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
    }
    else
    {
        return UIInterfaceOrientationMaskPortrait;
    }
}
Maice answered 30/4, 2015 at 11:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.