UIAlertView Dismiss На самом деле не отклонен

Ниже приведен код, который я использую для повторной попытки сеанса 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];
}

person Jim B    schedule 26.04.2010    source источник


Ответы (6)


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

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

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

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

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

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

но тогда у нас есть две другие проблемы, о которых нужно позаботиться:

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

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... но я думаю, что есть множество других способов проверить, является ли ключевое окно окном просмотра предупреждений... еще один, который приходит на ум, - это попробовать и посмотрите, что любой из его subView относится к классу "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];

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

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

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

person Alex Zak    schedule 20.07.2010

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

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

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

person kennytm    schedule 26.04.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];
//  }
}
person Jim B    schedule 26.04.2010

Другой вариант — изменить код 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];
}

to

UIWindow* window = [[UIApplication sharedApplication].windows objectAtIndex:0];
person Vincent Osinga    schedule 13.02.2012

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

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

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

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

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

person Mark A.    schedule 13.08.2010

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

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

, чтобы закрыть окно оповещения.

person christo16    schedule 26.04.2010
comment
Я не понимаю, didDismissWithButtonIndex выполняется в результате нажатия кнопки предупреждения. - person Jim B; 26.04.2010