Как скрыть баннер «Добро пожаловать обратно» при входе в Game Center

Я искал эту информацию в Интернете и в документах Apple, но не смог найти ответ... Знаете ли вы, есть ли способ скрыть сообщение «Добро пожаловать обратно, имя_игрока» от Game Center при аутентификации игрока?

Благодарю вас!


person Grhyll    schedule 07.09.2011    source источник
comment
Забавно, у меня в игре он не отображается (игровой центр работает, но приветственное сообщение не выводится), а я искал как заставить его отображаться.   -  person fbafelipe    schedule 20.01.2012
comment
Да, это можно сделать. Ответ опубликован ниже.   -  person BenW    schedule 30.07.2014


Ответы (5)


Нет, нет. Вы не можете изменить поведение сервисов iOS (частью которых является GameCenter) без джейлбрейка устройства и их переподключения. И из любопытства - зачем вам это?

person Kyr Dunenkoff    schedule 07.09.2011
comment
Жаль... Игра, над которой я работаю, позволяет вам зарегистрироваться на Open Feint и/или в Game Center, позволяя игроку выбрать свою любимую игру, чтобы отображать оповещения только от этой. Это довольно просто для достижений и автоматически для списков лидеров, но два сообщения появляются в то же время, когда игрок запускает игру, когда он входит в систему с обоими... - person Grhyll; 08.09.2011
comment
OpenFeint не является нативным сервисом, можете ли вы скрыть его сообщения? Лично я бы не стал использовать OpenFeint, если только не делал игру для Android. - person Kyr Dunenkoff; 08.09.2011
comment
Я думаю, должна быть возможность скрыть сообщение OpenFeint, но тогда, если игрок решил видеть только OpenFeint, но подписался на GameCenter, он увидит оба сообщения... - person Grhyll; 08.09.2011
comment
И игра именно для андроида тоже (и пк, и мака...) :) - person Grhyll; 08.09.2011
comment
Я предполагаю, что он тоже думает, что баннер чрезвычайно раздражает и мешает многим играм, даже если только на три секунды, и пользователь может провести его вверх. И я согласен; Apple должна обеспечить большую детализацию частоты отображения баннера. - person Nicolas Miari; 10.03.2014
comment
Да, приветственный баннер Game Center можно отключить программно. Код размещен ниже. - person BenW; 30.07.2014
comment
зачем тебе это надо? - Не могу ответить от имени ОП, но на мой взгляд баннер очень раздражает: он занимает значительное место от верхней части экрана (особенно в ландшафтных играх), и это особенно вредно в тетрис-подобных играх, где пользователь должен знать, что появляется в верхней части экрана как можно раньше. Это не было бы проблемой, если бы баннер появлялся сразу после запуска приложения (т. е. на главном экране); но вход в систему довольно медленный, и баннер обычно появляется в середине игры. - person Nicolas Miari; 03.12.2015

Да, можно программно подавить приветственный баннер Game Center из вашего приложения, по крайней мере, в iOS 7. Мой подход основан на нескольких наблюдениях:

  1. Баннер представлен как дополнительный UIWindow в вашем UIApplication.
  2. Это окно всегда отображается с индексом 1 (при условии, что ваше приложение использует только одно окно).
  3. Баннер имеет высоту 66 пикселей на iPad и 64 на iPhone.
  4. Баннер содержит подвид 42x42 пикселя для значка Game Center.
  5. Известно, когда может появиться баннер. (т. е. в течение нескольких секунд после создания объекта GKLocalPlayer при запуске для проверки аутентификации.)

Таким образом, вы можете просто несколько раз опрашивать окна вашего приложения в течение этих нескольких секунд, ожидая появления дополнительного окна. (Наблюдение за ключом и значением, вероятно, является «правильным» способом сделать это, но я ленив.) Когда появится окно, проверьте, содержит ли оно иерархию подпредставления, как описано выше, что указывает на то, что это, вероятно, баннер Game Center. Если это так, установите альфа окна на 0. Вот и все.

Вот некоторый код, который выполняет это в моем приложении. Я вызываю этот метод сразу после попытки аутентифицировать локального игрока, и он вызывает себя в течение нескольких секунд, пока не найдет (и не скроет) баннер, или же истечет время ожидания:

- (void)suppressGCBanner:(id)object {
    int osVersion = [[[UIDevice currentDevice] systemVersion] intValue];
    if (osVersion != 7) return;  // only tested against iOS 7

    static int iter = 0;    // try for 4 seconds, typically takes about one second for banner to appear
    static int origWindowCount = 0;

    NSArray* windows = [UIApplication sharedApplication].windows;
    if (origWindowCount == 0) origWindowCount = (int)[windows count];

    BOOL ipad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
    float bannerHeight = ipad ? 66.0f : 64.0f;  // GC banner has height 66 on iPad, 64 on iPhone

    if ([windows count] > origWindowCount) {
        NSLog(@"suppressGCBanner: found extra window, testing");

        UIWindow* window = [windows objectAtIndex:1]; // in my testing, the GC banner is always at index 1

        for (UIView* view in [window subviews]) {
            CGRect frame = view.frame;
            NSLog(@"subview size: %f, %f", frame.size.width, frame.size.height);

            if (frame.size.height != bannerHeight) continue;

            for (UIView* subview in [view subviews]) {
                CGRect frame = subview.frame;
                NSLog(@"sub-subview size: %f, %f", frame.size.width, frame.size.height);

                if (frame.size.width == 42.0f && frame.size.height == 42.0f) { // Game Center icon is 42x42
                    NSLog(@"found GameCenter banner: hiding. iter = %i", iter);

                    window.alpha = 0.0f; // make the window invisible!

                    return;
                }
            }
        }
    }

    if (++iter > 200) {
        NSLog(@"suppressGCBanner: timeout, bailing");
        return;
    }

    // ____ otherwise recurse
    [self performSelector:@selector(suppressGCBanner:) withObject:nil afterDelay:0.02f];
}

Время от времени вы увидите мерцающую линию в один пиксель в верхней части экрана, прежде чем баннер будет скрыт, но в целом этот метод работает достаточно хорошо. Используйте на свой страх и риск и наслаждайтесь!

person BenW    schedule 30.07.2014
comment
Извинения за отрицательный голос; это был неверный клик. Отредактируйте свой ответ, и я изменю его. (Это не позволит мне повторно щелкнуть, если ответ не будет отредактирован.) Этот код не использует частные API, поэтому у Apple нет оснований его отклонять. - person BenW; 31.07.2014
comment
Apple также может отклонить ваше приложение за злоупотребление публичными API; не только для использования частных. Просто говорю... - person Nicolas Miari; 03.12.2015

Вот более короткая версия для Swift:

//Call it right after create this object:
let localPlayer = GKLocalPlayer.localPlayer()
suppressGCBanner(0, originalWindowCount: UIApplication.sharedApplication().windows.count)

////////////////////////////////////////////////////////////////////////

static func suppressGCBanner(iteration: Int, originalWindowCount: Int) {
    let windows = UIApplication.sharedApplication().windows

    if windows.count > originalWindowCount {
        let window = windows[1]

        if window.respondsToSelector("currentBannerViewController") || window.respondsToSelector("bannerSemaphore") {
            print("Found banner, killing it \(iteration)")
            window.hidden = true
            return
        }
    }

    if iteration > 200 {
        print("suppressGCBanner: timeout, bailing")
        return
    }

    runThisAfterDelay(seconds: 0.02, after: {
        suppressGCBanner(iteration + 1, originalWindowCount: originalWindowCount)
    })
}

static func runThisAfterDelay(seconds seconds: Double, after: () -> ()) {
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue(), after)
}
person Esqarrouth    schedule 16.03.2017

Вы можете выйти из Game Center, если это для вас вариант. Большинство игр основаны на реакции, и уведомление, блокирующее 15% экрана на 3 секунды, явно не будет оценено.

person Neonfox    schedule 30.03.2013

Вот рабочая версия, адаптированная для swift3:

NameOfYourClass.suppressGCBanner(0, originalWindowCount: UIApplication.shared.windows.count)

static func suppressGCBanner(_ iteration: Int, originalWindowCount: Int) {

    let windows = UIApplication.shared.windows

    if windows.count > originalWindowCount {
        let window = windows[1]
        if window.responds(to: Selector("currentBannerViewController")) || window.responds(to: Selector("bannerSemaphore")) {
            print("Found banner, killing it \(iteration)")
            window.isHidden = true
            return
        }
    }

    if iteration > 200 {
        print("suppressGCBanner: timeout, bailing")
        return
    }

    runThisAfterDelay(seconds: 0.02, after: {
        suppressGCBanner(iteration + 1, originalWindowCount: originalWindowCount)
    })
}

static func runThisAfterDelay(seconds: Double, after: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
        after()
    }
}
person IgorAusBerlin    schedule 18.08.2017