UIAlertView解雇并未真正被驳回

时间:2010-04-26 16:20:28

标签: iphone uialertview fbconnect dismiss

下面是我用来在FBConnect会话上重试的代码。当[self loginToFaceBook]触发FBConnect时,将子视图添加到仍然是UIAlert视图的“window”,所以当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 个答案:

答案 0 :(得分:3)

我刚才有同样的问题...... 经过一番头痛我解决了......:D

(如果您不需要解释,只需查看示例代码,以及它上面的几行......:D)

问题是,alertView创建另一个窗口,使其成为关键窗口,并将alertView的视图放入其中......现在,当您告诉FBConnect重新登录时,使用对话框和所有内容,它显示它是自己的内部关键窗口。当时是alertView的窗口。

因此我们只需要设置警报窗口以重新设置其关键状态。 我没有办法手动做到这一点,但幸运的是,它为你做到了。什么时候?在运行循环结束时(它实际上需要一点时间;))。

解决方案非常简单,让警报的runloop结束。您可以通过在后台运行重新登录方法来完成此操作。

[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中是否合法...但我认为还有各种其他方法来检查关键窗口是否是警报视图的窗口...另一个想到的是尝试看到它的任何子视图是“UIAlertView”类...就像这样:

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

无论如何,我确定这是一个可以解决的问题......在我提交我的应用程序后,如果我还记得(我有记忆问题:/)我会让你们知道苹果是否批准了这些技术......

,你需要的另一件事是在主线程上“显示”对话框。但这很简单:

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

如果你想用会话初始化对话框,你也需要在主线程上做到这一点......

我有一个名为“showDialodWhenAppropriate”的方法,我在后台执行。它做了等待,当它适当的时候,我调用另一个叫做“showTheDialog”的方法,我在主线程上调用它。

Facebook应该自己实现这个......但是直到他们这样做,玩得开心。 :d

答案 1 :(得分:2)

您可以稍微延迟操作,让窗口有时间订购:

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

当然,您需要确保没有其他堆叠警报(使用公共API无法检查,因为这些警报可能来自系统,例如电量不足,推送通知等)。

答案 2 :(得分:0)

此代码仅适用于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];
//  }
}

答案 3 :(得分:0)

同样的问题,但很容易修复。我用一个计时器来触发我调用的fb方法。我试图向用户墙发布消息。我从didDismissWithButtonIndex触发了该方法:也是。

在FBDialog show:方法中,它调用当前窗口并显示新对话框。我相信FBConnect使用的任何对话都可以做到这一点。

我用定时器设置为半秒触发了该方法。它允许Alert很好地关闭,然后FBDialog框在正确的窗口中打开。使用按钮索引的开关盒,我有以下工作。

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

也许这也会奏效。

答案 4 :(得分:0)

另一种选择是更改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];

答案 5 :(得分:-1)

您需要致电:

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

取消警报视图。