I am trying to add High Scores in my game, and I don't know why i can't present the Leader boards. I can connect the user and send data. But can't see it.
My Game its in Cocos2d. But my MENU isn't when the user click on Play CCDirector Start
My main windows structure its:
-Navigation Contoller
- Menu -Ui View controller
- Navigation Item
I try to do it like a navigation and push it and crash. Also add it as subview. And crash. My leader boards code
- (IBAction)showLeader:(id)sender {
if ([self isGameCenterAvailable]) {
GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != nil) {
leaderboardController.leaderboardDelegate = self;
//[self presentModalViewController:leaderboardController animated:YES];
[self.navigationController pushViewController:leaderboardController animated:YES];
}
}
}
-(BOOL)isGameCenterAvailable {
// Check for presence of GKLocalPlayer API.
Class gcClass = (NSClassFromString(#"GKLocalPlayer"));
// The device must be running running iOS 4.1 or later.
NSString *reqSysVer = #"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
return (gcClass && osVersionSupported);
}
What could i do?
And another question. Could i put my own effect to present the leader bords scores? Or apple will reject it?
I am trying to do a small framework. So i don't need to codify allot in the Menu Game etc..
Thanks :D
I found how to do this.
menu2Game = [[Menu2Game alloc] initWithNibName:#"Menu2Game" bundle:nil];
menu2Game.wantsFullScreenLayout = YES;
[self.view addSubview:menu2Game.view];
[menu2Game presentModalViewController:leaderboardController animated:YES];
menu2Game its a clean View Controller. Maybe I can create a view controller temporally here. But I need to save it somewhere so i could dismiss it.
It work. But i am trying to do it in a landscape
Related
OK, so I'm trying to show Apple Game Center Leaderboards called from within my cocos2d game.
I've had some trouble doing so.
I did eventually stumble upon this and I implemented the following in one of my CCScene classes (I slightly modified the original code to prevent a compiler warning).
- (void)showLeaderboardForCategory:(NSString *)category
{
// Create leaderboard view with default Game Center style
leaderboardController = [[GKLeaderboardViewController alloc] init];
// If view controller was successfully created...
if (leaderboardController != nil)
{
// Leaderboard config
leaderboardController.leaderboardDelegate = self; // leaderboardController will send messages to this object
leaderboardController.category = category;
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
// Create an additional UIViewController to attach the GKLeaderboardViewController to
vc = [[UIViewController alloc] init];
// Add the temporary UIViewController to the main view
[[CCDirector sharedDirector].view.window addSubview:vc.view];
// Tell UIViewController to present the leaderboard
[vc presentModalViewController:leaderboardController animated:YES];
}
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[vc dismissViewControllerAnimated:YES completion:nil];
}
And, it works! At least when I call it, it does display the Leaderboard properly.
The only problem is, when I tap "Done" on the Leaderboard and the modal view dismisses, my CCScene no longer responds to tap events.
What do I need to do to regain responsiveness?
Refer sample plain cocos2d project:
-(void)showLeaderboard
{
GKLeaderboardViewController *leaderboardViewController = [[GKLeaderboardViewController alloc] init];
leaderboardViewController.leaderboardDelegate = self;
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] presentModalViewController:leaderboardViewController animated:YES];
[leaderboardViewController release];
}
Delegate Function:
-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
I'm developing an Augmented Reality application, everything worked properly till now that I need two different kind of visualization (AR and Map) depending on the device orientation. In particular the application should use the landscapeViewController when the device is in landscape mode while it should use another controller (named faceUpViewController ) when the device's orientation is "face up". I tried doing it with two simple view controllers and it works fine. The problem happens when the landscapeViewController uses the AR controller. The view is completely white and I don't understand why. Both the two controllers are "contained" by a Root View Controller. I'm doing everything by coding so without nib files. Here is the code:
RootViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
- (void)deviceOrientationDidChange:(NSNotification *)notification{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeLeft) {
if (self.landscapeViewController.view.superview == nil) {
if (self.landscapeViewController == nil) {
LandscapeViewController *lvc = [[LandscapeViewController alloc] init];
self.landscapeViewController = lvc;
[lvc release];
}
[self.faceUpViewController.view removeFromSuperview];
[self.view addSubview:self.landscapeViewController.view];
}
}
if (orientation == UIDeviceOrientationFaceUp) {
if (self.faceUpViewController.view.superview == nil) {
if (self.faceUpViewController == nil) {
FaceUpViewController *fvc = [[FaceUpViewController alloc] init];
self.faceUpViewController = fvc;
[fvc release];
}
[self.landscapeViewController.view removeFromSuperview];
[self.view addSubview:self.faceUpViewController.view];
}
}
}
#end
LandscapeViewController.m
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
UIView *landscapeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
landscapeView.backgroundColor = [UIColor yellowColor];
self.view = landscapeView;
[landscapeView release];
ARController *arC = [[ARController alloc] initWithViewController:self];
arC.landscapeViewController = self;
self.arController = arC;
[arC release];
}
//When the view appear present the camera feed
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[_arController presentModalARControllerAnimated:NO];
}
FaceUpViewController.m
- (void)loadView
{
UIView *faceUpView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
faceUpView.backgroundColor = [UIColor blueColor];
self.view = faceUpView;
[faceUpView release];
}
ARController.m Very simple version
- (id) initWithViewController:(UIViewController *)theView{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.rootController = theView;
//Retrieve screen bounds
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIView *overlaidView = [[UIView alloc] initWithFrame: screenBounds];
self.overlayView = overlaidView;
[overlaidView release];
self.rootController.view = overlayView;
// Initialise the UIImagePickerController
UIImagePickerController *picker= [[UIImagePickerController alloc] init];
self.pickerController = picker;
[picker release];
self.pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.pickerController.cameraViewTransform = CGAffineTransformScale(
self.pickerController.cameraViewTransform, 1.0f, 1.12412f);
self.pickerController.showsCameraControls = NO;
self.pickerController.navigationBarHidden = YES;
self.pickerController.cameraOverlayView = _overlayView;
}
return self;
}
- (void)presentModalARControllerAnimated:(BOOL)animated{
[self.rootController presentModalViewController:[self pickerController] animated:animated];
self.overlayView.frame = self.pickerController.view.bounds;
}
#end
I say again that I'm doing everything by coding thereby without nib files.
I really appreciate any advice!
Thanks
The primary problem with adding and removing your "child" view controllers' views as you've done here is that the view controller life cycle methods (viewWillAppear:, viewDidAppear:, etc.) won't ever get called on your child view controllers. Containers like UINavigationController and UITabBarController have always known how to delegate methods like these appropriately to their children, but UIViewController didn't officially support the ability to nest view controllers under your own custom container before iOS 5. It was possible, but it took a lot more work to do it right.
If you want to stick with the approach of adding and removing subviews, you have two options:
Require iOS 5+, and call addChildViewController:, removeFromParentViewController,
transitionFromViewController:toViewController:duration:options:animations:completion:,
willMoveToParentViewController:, and
didMoveToParentViewController: as described in the Implementing a Container View Controller section of the UIViewController Class Reference.
To support older iOS versions, you'll have to override many of the methods of the UIViewController class and delegate those calls manually to your child view controllers to make them behave as expected. I'd pay particular attention to the sections titled, "Responding to View Events", and "Responding to View Rotation Events" in the UIViewController Class Reference.
A different approach for pre-iOS 5 support is to present your child view controllers using presentModalViewController:animated: rather than adding their views as subviews to a container. Apple describes this approach in the View Controller Programming Guide for iOS under the section, Creating an Alternate Landscape Interface. The advantage of this approach is that your child view controllers are officially supported as first-class members of the view controller hierarchy, so UIKit will automatically manage their life cycles appropriately. You won't have to override and delegate all those methods manually.
You might want to try getting your acceptance rate up a little bit - more people would be willing to help you.
Anyway, wild guess: in your root controller, try putting the contents of
deviceOrientationDidChange
into
deviceOrientationWillChange.
I am trying to integrate Apple's game center into my application. I can successfully post scores to the leader board, and show the leader board, but the problem comes when I try to dismiss the leader board modal view. I've followed apple's code direction from the Game Kit Programming Guide ([url]http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/LeaderBoards/LeaderBoards.html[/url]).
My code is as follows for Game Center:
-(BOOL)isGameCenterAvailable{
// Check for presence of GKLocalPlayer class.
BOOL localPlayerClassAvailable = (NSClassFromString(#"GKLocalPlayer")) != nil;
// The device must be running iOS 4.1 or later.
NSString *reqSysVer = #"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
return (localPlayerClassAvailable && osVersionSupported);
}
- (void) authenticateLocalPlayer
{
if([self isGameCenterAvailable]){
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[localPlayer authenticateWithCompletionHandler:^(NSError *error) {
if (localPlayer.isAuthenticated)
{
// Perform additional tasks for the authenticated player.
}
}];
}
}
- (void) reportScore: (int64_t) score forCategory: (NSString*) category
{
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
scoreReporter.value = score;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
// handle the reporting error
}
}];
}
- (void) showLeaderboard
{
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil)
{
leaderboardController.leaderboardDelegate = self;
[self presentModalViewController: leaderboardController animated: YES];
}
//[leaderboardController release];
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
if([self modalViewController] != nil){
[self dismissModalViewControllerAnimated:YES];
}
}
-(IBAction)show{
[self showLeaderboard];
}
-(IBAction)submit{
[self reportScore:9 forCategory:kLeaderboardID];
}
Xcode tells me the problem line is [self dismissModalViewControllerAnimated:YES]; it says I'm getting bad access, which I know means I'm trying to access a bad pointer, but I don't see why anything wouldn't be invalid. Self reports that it has a modalviewcontroller. I've tried all sorts of variants, and I'm completely baffled as to why it is giving me errors.
Any help or suggestions would be greatly appreciated.
Thanks in advance!
I just had a very similar issue on my App. I discovered that it was not related to the ModalViewController itself but the view controller displaying it.
If you profile the app using the zombies option in the Profiler, you will be able to see that something is being released that should not be (Most likely a UIImage or UIView). You should be able to track down the function where the zombied object was allocated to find the real object causing the trouble.
I am supposing that the reason the error shows when the ModalViewController is dissmissed is that various view elements are called to redraw or refresh after the dialog goes away and then something gets accessed that was released when it shouldn't have been.
Hope this helps.
Im having a strange problem that only occurs on the iPad version of my game. When I bring up the GameCenter leaderboard, it appears like normal. No issues there. But when you tap the close button the leader board disappears and the cocos2d scene goes black. No errors, nothing. Nothing I do can bring the screen back. Ive tried resuming the director and even tried some solutions on a similar thread.
Here is my code in the cocos2d scene. GCController is just a subclass of the RootViewController, nothing special:
tempVC = [[GCController alloc] init];
GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != nil)
{
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.category = [NSString stringWithFormat:#"%#%#", [self cleanString:selectedSong], #"TotalHD"];
leaderboardController.leaderboardDelegate = self;
[[[CCDirector sharedDirector] openGLView] addSubview:tempVC.view];
[tempVC presentModalViewController:leaderboardController animated:YES];
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[tempVC dismissModalViewControllerAnimated:YES];
[tempVC.view.superview removeFromSuperview];
[tempVC release];
}
Anyone have any ideas? If I can provide any more information let me know. Thanks.
You are not providing enough code. I see no fault in the code you are showing at the moment. Your most likely cause of a black screen (depending on how you do things) is that timers have been interrupted and you may need to reset them with
- (void) onEnter;
or
- (void) onEnterTransitionDidFinish;
If that isn't it then post more code and I will check back. We need to see when the view is presented and what it should return to.
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[tempVC dismissModalViewControllerAnimated:YES];
**[tempVC.view removeFromSuperview];**
}
Dear all, I have a navigation-based app with about 60 views.
I have run with the following :
1. Build and analyse : bulid is successful with no complains.
2. Instruments allocation and leaks : no leaks.
However, the app crashed in iPhone or iPad but works fine in simulator.
The crash occurs at around 50th view.
There is no crash reports but I do see LowMemory.log in the crashreporter folder.
I have upgraded my iphone and ipad to 4.2
Does anyone have ideas what could be wrong?
I have been reading and troubleshooting for a week.
Thank you for all the replies.
My app has a root view called contentViewController and users can navigate to 4 quizzes from here.
This is the code I use to return to my root view.
- (void)goHome {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: #"Warning"
message: #"Proceed?"
delegate: self
cancelButtonTitle:#"Yes"
otherButtonTitles:#"No",nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[[self navigationController] setNavigationBarHidden:NO animated:YES];
if (buttonIndex == 0) {
NSArray * subviews = [self.view subviews];
[subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
self.view = nil;
if (self.contentViewController == nil)
{
ContentViewController *aViewController = [[ContentViewController alloc]
initWithNibName:#"ContentViewController" bundle:[NSBundle mainBundle]];
self.contentViewController = aViewController;
[aViewController release];
}
[self.navigationController pushViewController:self.contentViewController animated:YES];
}
}
Sample code for pushing views :
-(IBAction) buttonArrowClicked:(id)sender {
NSURL *tapSound = [[NSBundle mainBundle] URLForResource: #"click"
withExtension: #"aif"];
// Store the URL as a CFURLRef instance
self.soundFileURLRef = (CFURLRef) [tapSound retain];
// Create a system sound object representing the sound file.
AudioServicesCreateSystemSoundID (
soundFileURLRef,
&soundFileObject
);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![[defaults stringForKey:#"sound"] isEqualToString:#"NO"]) {
AudioServicesPlaySystemSound (soundFileObject);
}
if (self.exercise2ViewController == nil)
{
Exercise2ViewController *aViewController = [[Exercise2ViewController alloc]
initWithNibName:#"Exercise2ViewController" bundle:[NSBundle mainBundle]];
self.exercise2ViewController = aViewController;
[aViewController release];
}
[self.navigationController pushViewController:self.exercise2ViewController animated:YES];
}
You will normally not run into memory problems when running under the simulator, so these errors are not automatically encountered on this platform.
The simulator does however have a feature where you can manually trigger a Low Memory event. If this is actually the cause of the crash on the device, then it might also be possible that you can trigger the same bug in the simulator in this way.
Sharing some code about how you push the view controllers will allow others to help you with this.
You can pop to root view controller more easily by doing:
[self.navigationController popToRootViewControllerAnimated:YES];
You are actually pushing a new instance of your root view controller in the code that you have shared.