GKGameCenterViewController always shows Challenges instead of Leaderboards - ios

I'm using Apple's code to show a GKGameCenterViewController:
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
This is the text describing the code above:
Game Center UI is Displayed by Your View Controller (iOS)
The convention used by Game Kit is for one of your view controllers to present the Game Kit view controller. Your view controller acts as a delegate to the view controller it presents so that it can be informed when the player is finished looking at the presented screen. Listing 2-1 shows most common use of this pattern, which is to show the Game Center user interface. The Game Center view controller displays many different pieces of Game Center content, so most games should offer a button that brings the player to this screen, even if the game also shows Game Center content using a custom user interface.
When I use the recommended code I get to this screen (GameCenter Challenges), which is not what I want:
I have also tried this code:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"gamecenter:"]];
By using that code, I get to the screen I expected to display:
Do I misunderstand something or am I doing something wrong? Shouldn't the first piece of code bring me to the main menu? Why won't it show the leaderboards?
UPDATE
I implemented viewState as suggested by phix23:
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
But, it still displays the same Challenges screen, despite the fact that I want /try to display the Leaderboards screen.

The GKGameCenterViewController which is available since iOS 6 can show the leaderboards, achievements and challenges of your game center enabled application.
You can change the initial view by setting the viewState of the GKGameCenterViewController. If you don't set this property it will show the default view, which is the challenges view in your case. I guess you don't have setup any leaderboards or achievements so there is nothing to be shown.

Try using this code:
-(void)showGameCentersDefaultPage {
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateDefault;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
}
If you want to begin with a specific type of GameCenter Leaderboard you can call the following method with your leaderboardID
- (void)showLeaderboard:(NSString*)leaderboardID {
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
//The next three lines are the lines of interest...
gameCenterController.viewState = GKGameCenterViewControllerStateDefault;
gameCenterController.leaderboardTimeScope = GKLeaderboardTimeScopeToday;
gameCenterController.leaderboardCategory = leaderboardID;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
}

For iOS 7.0, I use the following:
Display Leaderboard:
- (void)displayLeaderboard:(UIViewController *)viewController
{
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
[viewController presentViewController:gameCenterController animated:YES completion:nil];
}
}
Display Achievements:
- (void)displayAchievements:(UIViewController *)viewController
{
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateAchievements;
[viewController presentViewController:gameCenterController animated:YES completion:nil];
}
}
Note that the view controller trying to use these functions will need to pass itself (i.e. viewController param must be set to some active view controller).
Hope this helps.

Use GKGameCenterViewController and set the view state:
//Create a leaderboard view controller
GKGameCenterViewController *leaderboardViewController = [[GKLeaderboardViewController alloc] init];
leaderboardViewController.viewState = GKGameCenterViewControllerStateLeaderboards;
//Set the time scope (ex. All Time, This Week, Today) and the leaderboard ID
leaderboardViewController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardViewController.leaderboardCategory = leaderboardID;
//Set the delegate so we can handle various actions including dismissal
leaderboardViewController.leaderboardDelegate = self;
//Present the view controller
[self presentViewController:leaderboardViewController animated:YES completion:nil];
This code will present a view controller that displays all of your games leaderboards (or the rankings if there is only one). You can also set properties such as which leaderboard to show, the time scope, delegate, etc. Also note that you can do a similar thing with achievements using the GKAchievementViewController.
The code that you provided in your question,
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"gamecenter:"]];
Launches the GameCenter app. This means that iOS will exit your app and switch to GameCenter. This could be confusing to the user. You should also avoid making the user leave your app. Instead, use the GKViewControllers which are presented modally inside of your app.

Related

When is a GKGameCenterViewController released?

The following documentation has the sample code below:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/LeaderBoards/LeaderBoards.html#//apple_ref/doc/uid/TP40008304-CH6-SW9
Listing 4-9 Displaying the leaderboard page of the Game Center user
interface
- (void) showLeaderboard: (NSString*) leaderboardID
{
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil)
{
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
gameCenterController.leaderboardTimeScope = GKLeaderboardTimeScopeToday;
gameCenterController.leaderboardCategory = leaderboardID;
[self presentViewController: gameCenterController animated: YES completion:nil];
}
}
When do you call "release" on the GKGameCenterViewController ? Should it be only after the view controller is dismissed, or can you call it at the end of this method ? Or should one just call autorelease ?
The project uses Automatic Reference Counting, therefore you do not need to explicitly declare release or dealloc. For reference, it is deallocated after the view leaves the view hierarchy.
I can't find any documentation to back this up (because all of Apple's documentation now assumes ARC), but my recollection from the pre-ARC days is that you release a modal view controller once you present it. I'm reasonably sure the presenting view controller will take a strong reference to the presented view controller. So:
- (void) showLeaderboard: (NSString*) leaderboardID
{
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil)
{
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
gameCenterController.leaderboardTimeScope = GKLeaderboardTimeScopeToday;
gameCenterController.leaderboardCategory = leaderboardID;
[self presentViewController: gameCenterController animated: YES completion:nil];
[gameCenterController release];
}
}
A better answer might be, "use ARC". :) Seriously, ARC rules.

Load and Display View While Interstitial is Shown

I have a UiViewController1 that loads an Admob interstitial, displays it when the user clicks a button, and loads another UiViewController2 when the user clicks out of the ad. However, I don't want the previous viewController to show, and the Admob interstitials are presented animated (I don't know of a way to stop this):
-(void)viewDidLoad {
[super viewDidLoad];
interstitial = [[GADInterstitial alloc] init];
interstitial.adUnitID = #"ca-app-pub-7102519969826764/7522738211";
interstitial.delegate = self;
GADRequest *request = [GADRequest request];
request.testDevices = [NSArray arrayWithObjects:GAD_SIMULATOR_ID,#"TheIDAppearingInLogs",nil];
[interstitial loadRequest:request];
}
-(void)onButtonPush {
if (interstitial.isReady) {
[interstitial presentFromRootViewController:self];
} else {
UIViewController2 *viewController = [[UIViewController2 alloc] init];
[self presentViewController:viewController animated:NO completion:nil];
}
}
-(void)interstitialDidDismissScreen:(GADInterstitial *)ad {
UIViewController2 *viewController = [[UIViewController2 alloc] init];
[self presentViewController:viewController animated:NO completion:nil];
}
I tried to load UIViewController2 before the ad is dismissed but, this happens:
Attempt to present <UIViewController1: 0x1355816a0>
on <UIViewController2: 0x135506490> whose view is not in the window hierarchy!
I guess you CANNOT modify AdMob SDK's viewController presenting behaviour,
actually what you are doing is not really common.
I would suggest to do some workaround f.e adding your viewController2 as a child instead of presenting modally in interstitialdidDismiss delegate

How to pull up a Gamecenter leaderboard with a button?

I am trying to use the button to pull up a single view Gamecenter leaderboard and cant really figure out how. I tried apples forums but didnt help so I came here. Help is appreciated
The view controller that will present the GKGameCenterViewController must conform to the <GKGameCenterControllerDelegate> protocol.
To present the leaderboard:
GKGameCenterViewController *leaderboardController = [[GKGameCenterViewController alloc] init];
if (leaderboardController != NULL) {
leaderboardController.gameCenterDelegate = self;
[self presentViewController:leaderboardController animated:YES completion:nil];
}

Apple's controllers not presenting properly in iOS7

In my iOS app i present standerd controllers MFMessageComposeViewController and UIImagePickerController.
But they both presenting with strange navigation bar.
How can i fix this problem?
UPD code for presenting controllers
UIImagePickerController:
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = sourceType;
cameraUI.allowsEditing = YES;
cameraUI.delegate = self;
[self presentViewController:cameraUI animated:YES completion:nil];
MFMessageComposeViewController:
MFMessageComposeViewController *messageViewController = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText]) {
messageViewController.view.backgroundColor = [UIColor whiteColor];
messageViewController.messageComposeDelegate = self;
recipient= [NSStringMask maskString:recipient withPattern:#"\\+(\\d{1}) \\((\\d{3})\\) (\\d{3})-(\\d{2})-(\\d{2})"];
messageViewController.recipients = #[recipient];
messageViewController.body = body;
[self presentViewController:messageViewController animated:YES completion:nil];
}
In iOS 7, the status bar and the navigation is translucent by default. To make the view act 'normal' like in iOS 6. you need to add this to the controller you are presenting.
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
If you want to read up more about changes in views. Check out this post. I find it a nice quick overview whats changed.
http://www.brianjcoleman.com/ios7-weve-got-a-problem/
See this question. I used the second answer, though I suspect the first would work for me also.

Game Center for iPad

GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != nil) {
// start the leader board view controller
leaderboardController.leaderboardDelegate = self;
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
leaderboardController.modalPresentationStyle = UIModalPresentationFullScreen;
leaderboardController.category = #"map1";
RootViewController* rootVC = ((AppDelegate*)[UIApplication sharedApplication].delegate).viewController;
[rootVC presentModalViewController:leaderboardController animated:YES];
}
I have a iPhone app, it works fine with gamecenter.
But when I build a iPad version, the gamecenter leaderboard still display with iPhone Size( 320x480 ).
So I added this:leaderboardController.modalPresentationStyle = UIModalPresentationFullScreen;
but the display is corrupted, the 3 buttons( today, this week, all time ) on tabbar are NOT fullscreen.
and a wood frame too.
you need to use the ModelPresentation Form Sheet which opens not in a full screen:
troller.modalPresentationStyle = UIModalPresentationFormSheet

Resources