Issue with Landscape View in Portrait App

Discussion in 'iOS Programming' started by RagingGoat, Jul 31, 2013.

  1. RagingGoat macrumors 6502

    Joined:
    Jun 21, 2010
    #1
    My app is portrait only except one view which contains an embedded YouTube video. That view is supposed to open in landscape and up until recently, worked just fine. The only change I have made to the app is to make it a universal app. I have made no changes to the code for this view though. It seems that the view initially loads ok in landscape if you are still holding the device in portrait. It doesn't crash until you actually rotate the device or, if you keep holding the device in portrait, press the play button. I tried adding the shouldAutoRotateMethod and returning NO and that causes the app not to crash but when pressing play it rotates back to portrait.

    Any ideas?

    The error is:
    Code:
    Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
    
    Here is my code:
    Code:
    #import "YouTubeView.h"
    #import <MediaPlayer/MediaPlayer.h>
    #import "KFBAppDelegate.h"
    @interface YouTubeView ()
    {
        UIWindow *window;
    }
    
    @end
    
    @implementation YouTubeView
    @synthesize thumbnailView;
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            thumbnailView.backgroundColor = [UIColor clearColor];
            KFBAppDelegate* myDelegate = (((KFBAppDelegate*) [UIApplication sharedApplication].delegate));
            window = myDelegate.window;
            // Custom initialization
    
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeFinished:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];
    
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        /*
    
    
    
    
    
        [self.view setBounds:CGRectMake( 0, 0, 480, 320)];
        [self.view setCenter:CGPointMake(160, 240)];
        [self.view setTransform:CGAffineTransformMakeRotation(M_PI/ 2)];
         */
        self.title = @"Monthly Video";
        // Do any additional setup after loading the view from its nib.
        // webView is a UIWebView, either initialized programmatically or loaded as part of a xib.
    
        int screenWidth = [UIScreen mainScreen].bounds.size.height;
        NSString *htmlString = [NSString stringWithFormat:@"<html><head><meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = no, width = %d\"/></head><body style=\"background:#000;margin-top:10px;margin-left:0px\"><div><object width=\"220\" height=\"128\"><param name=\"movie\" value=\"http://www.youtube.com/embed/videoseries?list=PL0B9BF37A24840E28&hl=en_US""></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/embed/videoseries?list=PL0B9BF37A24840E28&hl=en_US""type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"%d\" height=\"218\"></embed></object></div></body></html>",screenWidth,screenWidth];
    
    
        [thumbnailView loadHTMLString:htmlString baseURL:[NSURL URLWithString:@"http://www.youtube.com/playlist?list=PL0B9BF37A24840E28&feature=plcp"]];
    
    }
    
    -(IBAction)back:(id)sender
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
    {
        return UIInterfaceOrientationLandscapeLeft;
    }
    
    -(NSUInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskLandscape;
        // return UIDeviceOrientationLandscapeLeft | UIDeviceOrientationLandscapeRight | UIDeviceOrientationPortraitUpsideDown;
    }
    -(void)youTubeStarted:(id)sender
    {
        NSLog(@"Video Starting");
    
    }
    -(void)youTubeFinished:(id)sender
    {
        NSLog(@"bye");
    }
    @end
    
     
  2. xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #2
    Is a root view controller set?
    and out of curiosity, is the iPad an iPad2?
    I have some "different" behaviour on iPad2 I had to fix,
    but I didn't have to support portrait at all.
     
  3. RagingGoat thread starter macrumors 6502

    Joined:
    Jun 21, 2010
    #3
    Yes, there is a rootViewController set. Here is the AppDelegate.

    Code:
    #import "KFBAppDelegate.h"
    #import "KFBViewController.h"
    #import "KFBMasterViewController.h"
    #import "KFBDetailViewController.h"
    #import "AboutUs.h"
    #import "ContactUs.h"
    #import "KYFB.h"
    #import "KFBNavControllerViewController.h"
    #import "KFBTabBarViewController.h"
    #import "ActionAlertsViewController.h"
    #import "UAirship.h"
    #import "UAPush.h"
    #import "UAAnalytics.h"
    #import "WebViewController.h"
    
    @implementation KFBAppDelegate
    
    @synthesize detailViewManager, detailNavController;
    
    - (void)customizeApparance
    {
        UIImage *navBar = [[UIImage imageNamed:@"ButtonImage"]
                           resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        
        // Set the background image for *all* UINavigationBars
        [[UINavigationBar appearance] setBackgroundImage:navBar
                                           forBarMetrics:UIBarMetricsDefault];
        
        // Customize the title text for *all* UINavigationBars
        [[UINavigationBar appearance] setTitleTextAttributes:
         [NSDictionary dictionaryWithObjectsAndKeys:
          [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
          UITextAttributeTextColor,
          [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
          UITextAttributeTextShadowColor,
          [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
          UITextAttributeTextShadowOffset,
          [UIFont fontWithName:@"FranklinGothicStd-ExtraCond" size:28.0],
          UITextAttributeFont,
          nil]];
    }
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [self customizeApparance];
        
        // This prevents the UA Library from registering with UIApplcation by default when
        // registerForRemoteNotifications is called. This will allow you to prompt your
        // users at a later time. This gives your app the opportunity to explain the benefits
        // of push or allows users to turn it on explicitly in a settings screen.
        // If you just want everyone to immediately be prompted for push, you can
        // leave this line out.
        // [UAPush setDefaultPushEnabledValue:NO];
        
        //Create Airship options dictionary and add the required UIApplication launchOptions
        NSMutableDictionary *takeOffOptions = [NSMutableDictionary dictionary];
        [takeOffOptions setValue:launchOptions forKey:UAirshipTakeOffOptionsLaunchOptionsKey];
        
        // Call takeOff (which creates the UAirship singleton), passing in the launch options so the
        // library can properly record when the app is launched from a push notification. This call is
        // required.
        //
        // Populate AirshipConfig.plist with your app's info from https://go.urbanairship.com
        [UAirship takeOff:takeOffOptions];
        
        // Set the icon badge to zero on startup (optional)
        [[UAPush shared] resetBadge];
        
        // Register for remote notfications with the UA Library. This call is required.
        [[UAPush shared] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                             UIRemoteNotificationTypeSound |
                                                             UIRemoteNotificationTypeAlert)];
        
        // Handle any incoming incoming push notifications.
        // This will invoke `handleBackgroundNotification` on your UAPushNotificationDelegate.
        [[UAPush shared] handleNotification:[launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
                           applicationState:application.applicationState];
    
        
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        
        // Override point for customization after application launch.
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
        {
            KFBViewController *rootView = [[KFBViewController alloc] initWithNibName:@"KFBViewController" bundle:nil];
            
            KFBNavControllerViewController *navController = [[KFBNavControllerViewController alloc] initWithRootViewController:rootView];
            navController.delegate = rootView;
            
            UIViewController *aboutUs = [[AboutUs alloc] initWithNibName:@"AboutUs" bundle:nil];
            KFBNavControllerViewController *navController1 = [[KFBNavControllerViewController alloc] initWithRootViewController:aboutUs];
            
            UIViewController *contactUs = [[ContactUs alloc] initWithNibName:@"ContactUs" bundle:nil];
            KFBNavControllerViewController *navController2 = [[KFBNavControllerViewController alloc] initWithRootViewController:contactUs];
            
            UIViewController *kyfb = [[KYFB alloc] initWithNibName:@"KYFB" bundle:nil];
            KFBNavControllerViewController *navController3 = [[KFBNavControllerViewController alloc] initWithRootViewController:kyfb];
            
            self.tabBarController = [[KFBTabBarViewController alloc] init];
            self.tabBarController.viewControllers = @[navController, navController1, navController2, navController3];
            
            self.viewController = [[KFBViewController alloc] initWithNibName:@"KFBViewController" bundle:nil];
            self.window.rootViewController = self.tabBarController;
        }
        else
        {
            KFBMasterViewController *masterViewController = [[KFBMasterViewController alloc] initWithNibName:@"KFBMasterViewController_iPad" bundle:nil];
            UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
            
            KFBDetailViewController *detailViewController = [[KFBDetailViewController alloc] initWithNibName:@"KFBDetailViewController_iPad" bundle:nil];
            // UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
            
            detailNavController = [[UINavigationController alloc]initWithRootViewController:detailViewController];
        	
        	masterViewController.detailViewController = detailViewController;
        	
            self.splitViewController = [[UISplitViewController alloc] init];
            self.splitViewController.delegate = detailViewController;
            self.splitViewController.viewControllers = @[masterNavigationController, detailNavController];
            
            self.window.rootViewController = self.splitViewController;
        }
        [self.window makeKeyAndVisible];
        
        // If application is launched due to  notification,present another view controller.
        UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        
        if (notification)
        {
            if ([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
            {
                ActionAlertsViewController *actionAlerts = [[ActionAlertsViewController alloc] initWithStyle:UITableViewStylePlain];
                WebViewController *wvc = [[WebViewController alloc]init];
                [actionAlerts setWebViewController:wvc];
                KFBNavControllerViewController *navController7 = [[KFBNavControllerViewController alloc] initWithRootViewController:actionAlerts];
                actionAlerts.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Dismiss" style:UIBarButtonItemStyleBordered target:self action:@selector(dismiss)];
                [self.window.rootViewController presentViewController:navController7 animated:NO completion:nil];
            }
            /*
            else
            {
                ActionAlertsViewControlleripadViewController *actionAlertsIpad = [[ActionAlertsViewControlleripadViewController alloc]initWithStyle:UITableViewStylePlain];
                WebViewController *wvc2 = [[WebViewController alloc]init];
                [actionAlertsIpad setWebViewController:wvc2];
                KFBNavControllerViewController *iPadNavController7 = [[KFBNavControllerViewController alloc]initWithRootViewController:actionAlertsIpad];
                actionAlertsIpad.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Dismiss" style:UIBarButtonItemStyleBordered target:self action:@selector(dismiss)];
                [self.window.rootViewController presentViewController:iPadNavController7 animated:NO completion:nil];
            }
            */
        }
    
        return YES;
    }
    
    - (IBAction)dismiss
    {
        [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
    }
    
    - (void)applicationWillResignActive:(UIApplication *)application
    {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }
    
    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }
    
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }
    
    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        UA_LDEBUG(@"Application did become active.");
        
        // Set the icon badge to zero on resume (optional)
        [[UAPush shared] resetBadge];
    }
    
    - (void)applicationWillTerminate:(UIApplication *)application
    {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        [UAirship land];
    }
    
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        // Updates the device token and registers the token with UA.
        [[UAPush shared] registerDeviceToken:deviceToken];
    }
    
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error
    {
        UA_LERR(@"Failed To Register For Remote Notifications With Error: %@", error);
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    {
        
        UA_LINFO(@"Received remote notification: %@", userInfo);
        
        // Send the alert to UA so that it can be handled and tracked as a direct response. This call
        // is required.
        [[UAPush shared] handleNotification:userInfo applicationState:application.applicationState];
        
        // Optionally provide a delegate that will be used to handle notifications received while the app is running
        // [UAPush shared].delegate = your custom push delegate class conforming to the UAPushNotificationDelegate protocol
        
        // Reset the badge after a push received (optional)
        [[UAPush shared] resetBadge];
        
        if ([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
        {
            ActionAlertsViewController *actionAlerts = [[ActionAlertsViewController alloc] initWithStyle:UITableViewStylePlain];
            WebViewController *wvc = [[WebViewController alloc]init];
            [actionAlerts setWebViewController:wvc];
            KFBNavControllerViewController *navController7 = [[KFBNavControllerViewController alloc] initWithRootViewController:actionAlerts];
            actionAlerts.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc ] initWithTitle:@"Dismiss" style:UIBarButtonItemStyleBordered target:self action:@selector(dismiss)];
            [self.window.rootViewController presentViewController:navController7 animated:NO completion:nil];
        }
    }
    
    
    @end
    
    I am only having the problem on iPhone, not iPad.
     
  4. RagingGoat thread starter macrumors 6502

    Joined:
    Jun 21, 2010
    #4
    I fixed it my just enabling landscape left in supported device orientations. I'm still not sure why it didn't need to be enabled when this was just an iPhone app but it has fixed the crashing problem.
     

Share This Page