【问题标题】:UIAlertView Dismiss Not Really DismissedUIAlertView Dismiss 没有真正被解雇
【发布时间】:2011-02-12 11:45:22
【问题描述】:

下面是我用来重试 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];
}

【问题讨论】:

    标签: iphone uialertview fbconnect dismiss


    【解决方案1】:

    您需要致电:

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

    关闭警报视图。

    【讨论】:

    • 我不明白,didDismissWithButtonIndex 由于点击警报按钮而被执行。
    【解决方案2】:

    此代码仅适用于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】:

      您可以将操作延迟一点时间间隔,让窗口有时间点餐:

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

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

      【讨论】:

        【解决方案4】:

        我刚才也遇到了同样的问题... 在头疼之后,我解决了它......:D

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

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

        所以我们只需要让警报的窗口退出它的关键状态。 我没有找到手动执行此操作的方法,但幸运的是它为您做到了。什么时候?在运行循环结束时(实际上需要一点时间;))。

        解决方案很简单,让警报的运行循环结束。您可以通过在后台运行重新登录方法来做到这一点。

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

        但是我们还有另外两个问题需要处理:

        • 正如我之前提到的,实际上清理alertView 的混乱(尤其是窗口)需要一点时间。所以我们需要等待它。
        • FBConnect 创建的对话框内部有一个 webView,而 WebView 不喜欢在后台运行...所以我们需要在主线程中调用它。

        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

        【讨论】:

          【解决方案5】:

          同样的问题,但很容易解决。我使用计时器来触发我正在调用的 fb 方法。我试图向用户墙发布消息。我也从 didDismissWithButtonIndex: 触发了该方法。

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

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

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

          也许这也行。

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 2011-02-12
              • 2020-03-28
              • 2015-10-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-02-16
              相关资源
              最近更新 更多