Gamecenter authentication only in Cocos2d terrain with CCLayer for iOS 6

I have what seems to be a fairly common problem, but my searches and implementations for solutions didn't work.

I created a Cocos2d game that is only for terrain but needs to access the Gamecenter. Gamecenter works with portrait mode enabled, but also allows the game to switch to portrait mode.

I tried the following fixes:

Blocking the entrance to the game center in terrain only in i OS 6

Authenticating GameCenter in terrain-only app calls UIApplicationInvalidInterfaceOrientation

Error in iOS 6 after adding GameCenter to cocos2d landscaping app

Cocos 2d 2.0 shouldAutorotate not working?

I believe the problem is that I created the game using CCLayers instead of UIViewControllers

Example: MenuLayer.h

@interface MenuLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate, UINavigationControllerDelegate>{
   ..my header info..
}

      

MenuLayer.m

...
-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}
-(BOOL)shouldAutorotate {
    return [[UIDevice currentDevice] orientation] != UIInterfaceOrientationPortrait;
}

-(void)authenticateLocalPlayer
{

    GKLocalPlayer * localPlayer= [GKLocalPlayer localPlayer];

    if(localPlayer.authenticated == NO)
    {
        NSString *reqSysVer = @"6.0";
        NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
        {
            [[GKLocalPlayer localPlayer] setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) {
                if (viewcontroller != nil) {
                    AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
                    [[app navController] presentModalViewController:viewcontroller animated:YES];
                }else if ([GKLocalPlayer localPlayer].authenticated)
                {
                    //do some stuff
                }
            })];
        }
        else
        {
            [localPlayer authenticateWithCompletionHandler:^(NSError *error){
                if(localPlayer.isAuthenticated)
                {
                    //Peform Additionl Tasks for the authenticated player.
                }
            }];
        }
    }

}
...

      

Since I built the game using CCLayers instead of UIViewControllers, what are my alternatives? Am I correct in assuming that CCLayers do not call using supportedInterfaceOrientations or shouldAutorotate?

Or should I change this code somehow to fix the problem:

// Create a Navigation Controller with the Director
navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
navController_.navigationBarHidden = YES;

      

+1


source to share


1 answer


This also disappointed me. After a long search on the web, I found a couple of sources, and some worked with iOS 6, some with iOS5, but I had to make some changes to get them to work as I would like on iOS5 and iOS6. This is the code I am using, it works on my iPhone using 5.1 and 6. Note that the Game Center entry still appears in portrait orientation, it looks like there is nothing you can do about it. But the rest of the game will remain in landscape mode.

  • allow portrait mode as supported orientation in build settings (info.plist).
  • Create a new subclass of UINavigationController. Name this class whatever makes sense to you.
  • In your AppDelegate, include a new custom header file, UINavigationController.
  • In the App Delegate, comment out the original call and call your own class instead.

This should do the trick. Here is the code from my custom class:

#import <UIKit/UIKit.h>

@interface CustomNavigationViewController : UINavigationController

-(UIInterfaceOrientation) getCurrentOrientation;

@end

      

And the implementation file:



#import "CustomNavigationViewController.h"

@interface CustomNavigationViewController ()

@end

@implementation CustomNavigationViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

// This is required to allow GameCenter to login in portrait mode, but only allow landscape mode for the rest of the game play/
// Arrrgg!

-(BOOL) shouldAutorotate {
    return YES;
}

-(NSUInteger) supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

-(UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight; // or left if you prefer
}

-(NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        return UIInterfaceOrientationMaskLandscape;
    else {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
}

-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return [[UIDevice currentDevice] orientation] != UIInterfaceOrientationPortrait;
}

-(UIInterfaceOrientation) getCurrentOrientation {
    return [[UIDevice currentDevice] orientation];
}

@end

      

Please note that the latter method is getCurrentOrientation

not required. I just put it there to determine what the current orientation is.

Custom class is called in AppDelegate.m like this: (comment out the source)

navController = [[CustomNavigationViewController alloc] initWithRootViewController:director];
window.rootViewController = navController;
navController.navigationBarHidden = YES;
[window makeKeyAndVisible];

      

Hope it helps.

+5


source







All Articles