UIAlertView уволен не уволен - PullRequest
       24

UIAlertView уволен не уволен

1 голос
/ 26 апреля 2010

Ниже приведен код, который я использую для повторной попытки сеанса FBConnect. Когда [self loginToFaceBook] запускается, FBConnect добавляет подпредставление к 'окну', которое все еще является представлением UIAlert, поэтому, когда UIAlert действительно отклоняет его, оно берет представление FBConnect вместе с ним. Любая идея о том, как лучше всего дождаться исчезновения представления UIAlert.

-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if([self respondsToSelector:@selector(alertContinue)]) {
        [self alertContinue];
    }
}
-(void)alertContinue
{
    SocialLiteAppDelegate *appDelegate = (SocialLiteAppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDelegate.fbSession logout];
    [self loginToFaceBook];
}

Ответы [ 6 ]

3 голосов
/ 20 июля 2010

У меня была такая же проблема только сейчас ... После большой головной боли я решил это ...: D

(если вам не нужно объяснение, просто посмотрите на пример кода и несколько строк над ним ...: D)

Дело в том, что alertView создает другое окно, превращает его в ключевое окно и помещает в него представление alertView ... теперь, когда вы говорите FBConnect войти в систему с помощью диалога и всего, он показывает, что он внутри себя окно ключа. который в данный момент является окном alertView.

Так что нам просто нужно сделать окно оповещения, чтобы оставить его статус ключа. я не нашел способа сделать это вручную, но, к счастью, он сделает это за вас. когда? в конце цикла выполнения (и на самом деле это занимает немного времени;)).

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

[self performSelectorInBackground:@selector(loginToFaceBook) withObject:nil];

но у нас есть еще две проблемы:

  • Как я упоминал ранее, на самом деле требуется некоторое время, чтобы на самом деле очистить беспорядок в alertView (в частности, с окном). поэтому нам нужно подождать.
  • диалоговое окно, которое создает FBConnect, имеет веб-представление внутри, а веб-представлениям не нравится находиться в фоновом режиме ... поэтому нам нужно вызвать его в главном потоке.

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

BOOL shouldWait = YES ; 

// wait for the alert view to dissmiss it's self 
while (shouldWait) {

    [NSThread sleepForTimeInterval:0.1];

    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    shouldWait = [keyWindow isKindOfClass:NSClassFromString(@"_UIAlertOverlayWindow")];
}

Теперь я не уверен, допустимо ли это в общедоступном API ... но я думаю, что есть все другие способы проверить, является ли ключевое окно окном просмотра предупреждений ... еще один, который приходит на ум это попытаться увидеть его в любом из его подвидов класса "UIAlertView" ... вот так:

for (UIView *subView in [keyWindow subviews]) {
    if (shouldWait = [subView isKindOfClass:[UIAlertView class]) {
        break;
    }
}

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

и другое, что вам нужно, это «показать» диалог в главном потоке. но это легко:

FBStreamDialog* dialog = [[[FBStreamDialog alloc] init] autorelease];
[dialog performSelectorOnMainThread:@selector(show) withObject:nil];

если вы хотите начать диалог с сеансом, вам нужно сделать это и в основном потоке ...

У меня был метод с именем "showDialodWhenApp Соответствующий", который я выполняю в фоновом режиме. он выполняет ожидание, и когда это уместно, я вызываю другой метод с именем "showTheDialog", который я вызываю в главном потоке.

Фейсбук, вероятно, должен реализовать это самостоятельно ... но пока они этого не делают, веселитесь : D

2 голосов
/ 26 апреля 2010

Вы можете отложить действие с небольшим интервалом времени, чтобы окно успело оформить заказ:

-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if([self respondsToSelector:@selector(alertContinue)]) {
        [self performSelector:@selector(alertContinue) withObject:nil afterDelay:0.05];
    }
}

Конечно, вам нужно убедиться, что нет других суммированных оповещений (что невозможно проверить с помощью общедоступного API, потому что эти оповещения могут поступать из системы, например, низкий заряд батареи, push-уведомления и т.

0 голосов
/ 13 февраля 2012

Другой вариант - изменить код FBDialog.m. Измените этот бит кода:

UIWindow* window = nil;//[UIApplication sharedApplication].keyWindow; // this does not work if you come from a UIAlertView!!!
if (!window) {
    window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}

до

UIWindow* window = [[UIApplication sharedApplication].windows objectAtIndex:0];
0 голосов
/ 14 августа 2010

Та же проблема, но ее легко исправить. Я использовал таймер для запуска метода fb, который я вызывал. Я пытался отправить сообщение на стену пользователей. Я вызывал метод из didDismissWithButtonIndex: также.

В методе FBDialog show: он вызывает текущее окно и отображает новое диалоговое окно. Я полагаю, что любой диалог, используемый FBConnect, делает это.

Я запустил метод с таймером, установленным на полсекунды. Это позволяет красиво закрыть оповещение, и тогда окно FBDialog открывается в правильном окне. С помощью переключателя для указателя кнопок у меня отлично работает следующее.

    case 1:
            NSLog(@"Write On Wall");
            [self performSelector:@selector(postToWall) withObject:nil afterDelay:0.5f];
            break;

Может быть, это тоже сработает.

0 голосов
/ 26 апреля 2010

Этот код работает только для animated = NO.

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(buttonIndex == alertView.cancelButtonIndex) { 
        exit(0); 
    }
    [alertView dismissWithClickedButtonIndex:buttonIndex animated:NO];
    if([self respondsToSelector:@selector(alertContinue)]) {
        [self alertContinue];
    }
}

-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
//  if([self respondsToSelector:@selector(alertContinue)]) {
//      [self alertContinue];
//  }
}
0 голосов
/ 26 апреля 2010

Вам нужно позвонить:

 - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated

, чтобы закрыть окно предупреждения.

...