简体   繁体   中英

How to dismiss GKMatchmakerViewController if already being presented and present new instance when receiving invitation?

The following delegate method is called by gameKit, when a person accepts an invitation

-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
    NSLog(@"%@ accepted invite",player.playerID);

    RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
    [root popToRootViewControllerAnimated:YES];
    GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithInvite:invite];
    mmvc.matchmakerDelegate = root.viewControllers[0];
    [[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}

This "works" when the user is not already presenting a GKMatchmakerViewController .

This does not work if the user is already using the GKMatchmakerViewController when the invite comes in (Eg: When the user is already trying to find a match). If this is the case, when the invite comes in, I get the following warning, and the controller with the invite is not presented (since there is already a matchmakercontroller being presented). As a result, the user cannot respond to an invite. (Nothing happens).

Warning: Attempt to present <GKMatchmakerViewController: 0x1458a250>  on <RIYGameNavigationController: 0x1461f190> which is already presenting <GKMatchmakerViewController: 0x1465fcb0>

In iOS6, one could get around this by doing:

 if([topLevelViewController modalViewController] != nil)      
[topLevelViewController dismissModalViewControllerAnimated:NO];

and then creating the GKMatchmakerViewController . dismissModalViewControllerAnimated: has been deprecated in iOS6. It is suggested to use dissmissViewControllerAnimated:completion: instead, but it doesn't work for me. This is what I tried:

-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
    NSLog(@"%@ accepted invite",player.playerID);

    RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
    [root popToRootViewControllerAnimated:YES];
    if ([[root presentedViewController]class] == [GKMatchmakerViewController class]) {
        [root dismissViewControllerAnimated:YES completion:nil];
    }

    GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithInvite:invite];
    mmvc.matchmakerDelegate = root.viewControllers[0];
    [[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}

The if block gets entered, but the existing GKMatchmakerViewController is not dismissed, and the new one does not show up. If I put a break point in the if statement, when I "continue" after the break, the view controller is dismissed, but the new one does not pop up.

How can I get this working?

I got around this by presenting the view in the completion block.

- (void)presentMatchmakerViewControllerWithInvite:(GKInvite *)invite
{
    RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
    GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithInvite:invite];
    mmvc.matchmakerDelegate = root.viewControllers[0];
    [[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}

-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
     NSLog(@"%@ accepted invite",player.playerID);
     RIYGameNavigationController *root = (RIYGameNavigationController*)[[[UIApplication sharedApplication]delegate]window].rootViewController;
    [root popToRootViewControllerAnimated:YES];
    if ([[root presentedViewController]class] == [GKMatchmakerViewController class]) {
        [root dismissViewControllerAnimated:YES completion:^{
            [self presentMatchmakerViewControllerWithInvite:invite];
        }];
    }
    else
    {
        [self presentMatchmakerViewControllerWithInvite:invite];
    }
}

It seems to work, but I feel it is clumsy. If someone has a better answer I will mark that as the correct one

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM