I'm using GKAchievementViewController to display achievements. It works fine on most devices, but on some (iPod Touch 3rd Gen and iPad 1 running iOS 5.1.1) taping the Done button does nothing.
I have no idea how to debug this...
Here is the code I'm using to display the achievements:
viewController = [[GKAchievementViewController alloc] init];
if (viewController)
{
viewController.achievementDelegate = self;
[self presentModalViewController:viewController animated:YES];
}
and then:
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)aViewController
{
[self dismissModalViewControllerAnimated:YES];
}
Should work when implementing achievementViewControllerDidFinish:
- (void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
[viewController.delegate dismissModalViewControllerAnimated:YES];
}
Answering my own question in case anyone has the same problem.
This seems to have solved the issue:
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)aViewController
{
if ([self respondsToSelector:#selector(dismissViewControllerAnimated:completion:)])
{
[self dismissViewControllerAnimated:YES completion:^{
aViewController.achievementDelegate = nil;
[aViewController release];
}];
}
else
{
[self dismissModalViewControllerAnimated:YES];
aViewController.achievementDelegate = nil;
[aViewController release];
}
}
Related
I am having a small problem.I have a view which should be set to hidden when the view loads is tried to add
[self.view setHidden:YES];
in viewWillAppear and the view is hiding but the Hiding of view is visible(it takes a split second to hide after the app is loaded).I need to hide the view without it visible.Help me ?
My full code in viewDidAppear
-(void)viewDidAppear:(BOOL)animated
{
#try {
NSLog(#"\n\n--------------Mainview Controller------------\n");
// Guided access mode call mainview in iOS7. It making issue in UI
[getStartBox setHidden:NO];
appDel.deviceModel=[self platformString];
if([MainView checkRegistrationStatus])
{
NSLog(#"Already registered....");
[main setGlobalValues];
if ([appDel.configArray count]==0)
{
NSLog(#"Load app sync page...");
[self.view setHidden :YES];
// [_mainView setHidden:YES];
AppSync *sync=[[AppSync alloc]initWithNibName:#"AppSync" bundle:nil];
sync.appSyncData = configureData;
[self presentViewController:sync animated:NO completion:nil];
}
else
{
NSLog(#"%#",appDel.logInStatus);
if([appDel.logInStatus isEqualToString:#"false"])
{
[self.view setHidden :YES];
// [_mainView setHidden:YES];
NSLog(#"Load login view controller...");
appDel.isEmergencyAlertOn=NO;
appDel.isRespondingToAlert=NO;
LogInViewController *loginView=[[LogInViewController alloc]initWithNibName:#"LogInViewController" bundle:nil];
[self presentViewController:loginView animated:NO completion:nil];
}
else if([appDel.logInStatus isEqualToString:#"true"])
{
NSLog(#"Load alert screen");
[self.view setHidden :YES];
// [_mainView setHidden:YES];
AlertScreen *alert=[[AlertScreen alloc]initWithNibName:#"AlertScreen" bundle:nil];
alert.alertData=notificationData;
[self presentViewController:alert animated:NO completion:nil];
}
}
}
else
{
appDel.domainName=nil;
// Version number reffered in settings page. The log enabled one should be in same format (Ex Version 1.0.53(log enabled))
versionLabel.text=#"Version 1.3(log enabled)";//(log enabled)
appDel.appVersion=versionLabel.text;
//self.view.layer.contents=(id)[[UIImage imageNamed:#"background.png"]CGImage];
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]]];
ConfigureButton.hidden=NO;
}
}
#catch (NSException *exception) {
[[WriteLogger getWriteLogger] writeLog:moduleName sourceClass:self.nibName methodName:#"viewDidAppear" errorMsg:exception];
}
So I have a view controller from which I have an action method sendSMS, which creates the SMS View Controller... Problem is, when I actually send the message, the controller will not dismiss, or it won't create any logs, so I guess the didFinishWithResult method is not even called. Big thanks goes to all of you!
So, my .m looks like this:
- (void)presentViewController:(UIViewController *)controller animated:(BOOL)animated onComplete:(void (^)(void))callback
{
MIKEAppDelegate *APP_DELEGATE = [UIApplication sharedApplication].delegate;
UIViewController *presentedModalVC = [APP_DELEGATE.window.rootViewController presentedViewController];
if (presentedModalVC) {
while (presentedModalVC.presentedViewController) {
presentedModalVC = presentedModalVC.presentedViewController;
}
[presentedModalVC presentViewController:controller animated:animated completion:callback];
} else {
[APP_DELEGATE.window.rootViewController presentViewController:controller animated:animated completion:callback];
}
}
-(void)sendSMS
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
NSLog(#"SMS composer appeared");
controller.body = #"Testy Test";
controller.recipients = [NSArray arrayWithObjects:#"774252704", nil];
controller.messageComposeDelegate = self;
[controller presentViewController:controller animated:YES onComplete:nil];
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
// Notifies users about errors associated with the interface
switch (result)
{
case MessageComposeResultCancelled:
NSLog(#"Result: SMS sending canceled");
break;
case MessageComposeResultSent:
NSLog(#"Result: SMS sent");
break;
case MessageComposeResultFailed:
NSLog(#"Result: SMS sending failed");
break;
default:
NSLog(#"Result: SMS not sent");
break;
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
EDIT 1:
My .h looks like this:
#import <UIKit/UIKit.h>
#import <MessageUI/MFMessageComposeViewController.h>
#interface MIKETableViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate, MFMessageComposeViewControllerDelegate>
-(void)viewWillAppear:(BOOL)animated;
-(void) sendSMS;
#end
EDIT 2:
Ok I tried to launch sendSMS method by pressing button, and everything works as it should, so there is a problem in that HOW I call the method. Thing is that I call the method from myCustomTableCell Class... Idea is, when I slide the cell of the screen It will call the sendSMS method. Please see .m file from my custom cell
-(void)panGestureRecognizer:(UIPanGestureRecognizer *)sender{
CGPoint translation = [sender translationInView:self];
MIKETableViewController *mainController = [[MIKETableViewController alloc] init];
//NSLog(#"Panned with translation point: %#", NSStringFromCGPoint(translation));
sender.view.center = CGPointMake(sender.view.center.x + translation.x,
sender.view.center.y);
CGPoint breakingPoint = CGPointMake(320,sender.view.center.y);
CGPoint startPoint = CGPointMake(150, sender.view.center.y);
CGPoint endPoint = CGPointMake(500, sender.view.center.y);
if (sender.view.center.x <= startPoint.x) {
sender.view.center = startPoint;
}
if (sender.state == UIGestureRecognizerStateEnded) {
if (sender.view.center.x >= breakingPoint.x) {
[UIView animateWithDuration:0.2
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
sender.view.center = endPoint;
}
completion:^(BOOL finished){
NSLog(#"Bought!");
self.timeLabel.text = timeLabelValue;
self.priceLabel.text = priceLabelValue;
self.infoLabel.text = infoLabelValue;
[mainController tableView:mainController.self.tableView didSelectRowAtIndexPath:mainController.self.tableView.indexPathForSelectedRow];
[mainController sendSMS];
}];
} else {
//recognizer.view.center = startPoint;
[UIView animateWithDuration:0.2
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
sender.view.center = startPoint;
}
completion:^(BOOL finished){
NSLog(#"Returned!");
}];
}
}
[sender setTranslation: CGPointZero inView: self];
}
You are dismissing self in the mail composer delegate method, instead of the mail view controller, change:
[self dismissViewControllerAnimated:YES completion:NULL];
to
[controller dismissViewControllerAnimated:YES completion:NULL];
It should work, But your code looks proper, so most probably you have not conformed the delegate <MFMessageComposeViewControllerDelegate>
#Janak Nirmal : Sorry, In hurry i didn't see the delegate method implementation.
Put the break point in the delegate method and see whether the control comes to that method.
In sendSMS method use this code to present :
[self presentViewController:controller animated:YES completion:nil];
now check. and only when send or cancel button pressed, the delegate will be called.
EDIT
The problem is because of that method :
presentViewController:animated:onComplete:
On which controller you present from the same controller you need to dismiss.
For example :
[self presentViewController:viewController animated:YES onComplete:nil];
[self dismissViewControllerAnimated:YES completion:nil];
or
[[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:controller animated:animated completion:callback];
[[UIApplication sharedApplication].delegate.window.rootViewController
dismissViewControllerAnimated:YES completion:nil];
EDIT
Import this in your .h file
#import <MessageUI/MessageUI.h>
Add this header file and check whether the delegate is being called.
EDIT
So you are saying that :
messageComposeViewController:didFinishWithResult:
this delegate method even now is not getting called on clicking send or cancel????
EDIT
instead of this line of code
[controller presentViewController:controller animated:YES onComplete:nil];
put this code and tell me whether the delegate method being called
UIViewController *rootViewController = [[[[UIApplication sharedApplication] delegate] window]rootViewController];
[rootViewController presentViewController:viewController animated:YES completion:nil];
EDIT
Only way is left out is, give me access to your code somewhere in VCS and i will help you out with the problem.
I have a UIViewController on an iPad that I am displaying modally.
However after dismissing it, the view controller that displayed it does not change in orientation and acts as if the underlying view controller did not change, unless the device is rotated back and forth.
I'm using these methods in the modal view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
[self updateUI];
return YES;
}
- (BOOL)shouldAutorotate {
[self updateUI];
return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAll;
}
-(void) updateUI{
}
The underlying UINavigationController code (the one that doesn't change itself properly once the modal view controller is dismissed):
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
[self adjustUIForOrientation:interfaceOrientation];
return YES;
}
- (BOOL)shouldAutorotate {
[self adjustUIForOrientation:[self preferredInterfaceOrientationForPresentation]];
return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAll;
}
- (void) adjustUIForOrientation: (UIInterfaceOrientation)interfaceOrientation {
if(UIDeviceOrientationIsPortrait(interfaceOrientation)) {
[_landscapeTemplate hide];
[_portraitTemplate show];
_activeTemplate = _portraitTemplate;
} else {
[_portraitTemplate hide];
[_landscapeTemplate show];
_activeTemplate = _landscapeTemplate;
}
}
-(IBAction) signInButtonTouched: (id) sender{
if (![Session shared].loggedInUser){
UserProfileLoginViewController *userProfileLoginVC = [[[UserProfileLoginViewController alloc] initWithNibName:#"UserProfileLoginViewController" bundle:nil] autorelease];
userProfileLoginVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
self.modalPresentationStyle = UIModalPresentationCurrentContext;
//self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:userProfileLoginVC animated:YES completion:nil];
// [self pushViewController:userProfileLoginVC animated:YES];
[userProfileLoginVC.emailTextField becomeFirstResponder];
}
else [[Session shared] explicitEnd];
}
Is there a way to make this work? Basically it appears that the view controller that presented the modal view controller is not getting the rotation calls forwarded to itself.
We've just added Game Kit to our Cocos 2D game. It works fine, but causes some serious memory leaks. I've read all posts about it on this forum (and on other forums), but nothing seems to help. We're using the GameCenterManager from GKTapper.
This is how we create the leader board and show it:
-(void)showLeaderBoard:(NSString *)lb withScore:(int)score
{
GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != nil){
gcVC = [[UIViewController alloc] init];
leaderboardController.category = lb;
leaderboardController.timeScope = GKLeaderboardTimeScopeWeek;
leaderboardController.leaderboardDelegate = self;
[[[CCDirector sharedDirector] openGLView] addSubview: gcVC.view];
[gcVC presentModalViewController:leaderboardController animated:YES];
}
}
And here it's removed:
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[gcVC dismissModalViewControllerAnimated:YES];
[gcVC.view.superview removeFromSuperview];
[gcVC release];
}
The leak is obvious if you look at the used Real Mem in the activity monitor. The first time the leader board is shown and dismissed the app's memory usage has increased with 11.42MB, then it increases with ~0.3MB every time the leader board is shown and dismissed. Also, every time you browse between "Today", "This Week" and "All Time" in the game center leader board another ~0.2MB are eaten up.
I believe that code is old and was used before cocos2d added its own RootViewController. Here's the code that I'm using in KKGameKitHelper:
-(UIViewController*) getRootViewController
{
return (UIViewController*)((KKAppDelegate*)[UIApplication sharedApplication].delegate).rootViewController;
}
-(void) presentViewController:(UIViewController*)vc
{
UIViewController* rootVC = [self getRootViewController];
[rootVC presentModalViewController:vc animated:YES];
}
-(void) dismissModalViewController
{
UIViewController* rootVC = [self getRootViewController];
[rootVC dismissModalViewControllerAnimated:YES];
}
// Leaderboards
-(void) showLeaderboard
{
if (isGameCenterAvailable == NO)
return;
GKLeaderboardViewController* leaderboardVC = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardVC != nil)
{
leaderboardVC.leaderboardDelegate = self;
[self presentViewController:leaderboardVC];
}
}
-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController*)viewController
{
[self dismissModalViewController];
if ([delegate respondsToSelector:#selector(onLeaderboardViewDismissed)])
{
[delegate onLeaderboardViewDismissed];
}
}
I am trying to use dismissModalViewController:Animated: to dismiss my view, but it is not dismissing it, no matter what I try. You can see my attempts to release the view in the hideSplash method at the bottom. Please, if anyone can help it would be greatly appreciated. My code posted below:
#import "SplashViewController.h"
#implementation SplashViewController
- (void) didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void) viewDidUnload {
}
- (void) dealloc {
[super dealloc];
}
-(void) showSplash {
modalViewController = [[UIViewController alloc] init];
modalViewController.view = modelView;
[self presentModalViewController:modalViewController animated:NO];
[activityIndicator startAnimating ];
//[self bigcalculation];
//[self performSelector:#selector(hideSplash) withObject:nil afterDelay:2.0];
}
- (void) viewDidAppear:(BOOL)animated {
NSLog(#"View Did Appear");
[self bigcalculation];
}
- (void) bigcalculation {
NSLog(#"Big Calc Start");
for (int i = 0; i <= 648230; i++) {
for (int j = 0; j <= 1200; j++) {
}
}
NSLog(#"Big Calc End");
[self performSelector:#selector(hideSplash) withObject:nil];
}
- (void) hideSplash {
NSLog(#"Hide");
//[self dismissModalViewControllerAnimated:NO];
//[[self parentViewController] dismissModalViewControllerAnimated:YES];
[[self modalViewController] dismissModalViewControllerAnimated:YES];
NSLog(#"End Hide");
}
#end
The modal view controller is not responsible for dismissal. That burden is placed on the view controller that called the modalViewController.
Try replacing:
[[self modalviewController] dismissModalViewControllerAnimated:YES];
with
[self dismissModalViewControllerAnimated:YES];
Try to use this:
[self.parentViewController dismissModalViewControllerAnimated:NO];
I found the solution in case anyone else has this issue the line
[self performSelector:#selector(hideSplash) withObject:nil];
Should be
[self performSelector:#selector(hideSplash) withObject:nil afterDelay:0.0];