【问题标题】:Alert is not showing with in the -(void)alertView:clickedButtonAtIndex: method警报未在 -(void)alertView:clickedButtonAtIndex: 方法中显示
【发布时间】:2011-06-22 17:56:38
【问题描述】:

我正在开发这款 iPhone 应用程序,它具有基本的登录 - 注销功能。要求是执行如下注销操作。

  1. 首先使用 UIAlertView 获得用户的确认
  2. 在服务器中处理注销过程时显示正在进行的注销警告框

服务器逻辑尚未实现,但在显示第二个正在进行的警报框时我遇到了问题。问题是,没有显示警报框,而是主线程只是进入睡眠状态并进入根视图控制器。谁能帮我解决这个问题。

以下是我的代码:

注销操作:

-(IBAction)logOut
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Really Want to Log Out?" 
                     message:@"If you continue you will be redirected to Home page, 
                     where you have to sign in again. \n\nContinue?" 
                     delegate:self cancelButtonTitle:@"Cancel" 
                     otherButtonTitles:@"Continue", nil];

[alert show];

[alert release];

}

用户的输入(用户点击了哪个按钮)将按如下方式处理...

-(void)alertView:(UIAlertView *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        [NSThread detachNewThreadSelector:@selector(dataProcessor) 
                  toTarget:self withObject:nil];
        [NSThread sleepForTimeInterval:3];
        [self.navigationController popToRootViewControllerAnimated:YES];
    } else {
        // do nothing
    }
}

dataProcessor() 的实现如下:

-(void)dataProcessor { 

     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

     UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Signing out...\n\nPlease Wait..." 
                           message:nil delegate:self cancelButtonTitle:nil 
                           otherButtonTitles: nil] autorelease];

     [alert show];

     UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] 
                initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

     indicator.center = CGPointMake(alert.bounds.size.width / 2, 
                                    alert.bounds.size.height - 50);
     [indicator startAnimating];
     [alert addSubview:indicator];
     [indicator release];


     [alert dismissWithClickedButtonIndex:0 animated:YES];

     [pool release]; 

}

当我使用这种方法时,不会显示带有 UIActivityIndi​​cator 的警报。会发生什么是欢迎视图控制器变黑(我认为这是因为 [NSThread sleepForTimeInterval:3]; )并返回根视图控制器。

我也尝试过使用带有警报的标签,如本文所述。 Show Alert in clickedButtonAtIndex? 但我仍然无法让它工作。

请问谁能帮帮我?提前致谢。

【问题讨论】:

    标签: iphone objective-c uinavigationcontroller uialertview


    【解决方案1】:

    这里有很多问题。

    1. 在主线程以外的线程中处理 UIKit 元素。
    2. 您正在创建警报、显示它并立即将其关闭。当然,在计算机时代,这必须发生得非常快。所以你甚至不会看到它。
    3. 阻止用户界面。 (当然,这似乎是您想要的。)

    你应该这样做,

    -(void)alertView:(UIAlertView *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex == 1) {
            [self dataProcessor];
        } else {
            // do nothing
        }
    }
    

    后来在dataProcessor

    -(void)dataProcessor { 
         UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Signing out...\n\nPlease Wait..." 
                               message:nil delegate:self cancelButtonTitle:nil 
                               otherButtonTitles: nil] autorelease];
    
         [alert show];
    
         UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] 
                    initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    
         indicator.center = CGPointMake(alert.bounds.size.width / 2, 
                                        alert.bounds.size.height - 50);
         [indicator startAnimating];
         [alert addSubview:indicator];
         [indicator release];
    
         [self performSelector:@selector(dismissAndPop:) withObject:alert afterDelay:3.0f];
    }
    

    并在 .h 和 .m 中声明 dismissAndPop:

    - (void)dismissAndPop:(UIAlertView *)alertView {
        [alertView dismissWithClickedButtonIndex:0 animated:NO];
        [alertView release];
    
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    

    我刚刚更新了您的逻辑以显示警报视图,并在 3 秒后触发其解除,然后是 popViewControllerAnimated:

    【讨论】:

    • 嗨,Deepak,首先让我感谢您非常详细地回答我的问题。我刚刚开始 iPhone 编程,所以像你这样的答案会对我有很大帮助。我已按照您的步骤进行操作,并且能够满足要求。再次感谢数以百万计的 Deepak 的帮助。 :)
    【解决方案2】:

    您应该永远不要在主线程以外的任何地方编写作用于 UI 的代码。

    在用户界面上更改任何内容的每个代码都应在 UI 中完成。

    另外,使用[NSThread sleepForTimeInterval] 是一种阻塞方法,这是一种不好的做法(主动等待与被动等待)

    如果您无法使用委托方法通知您处理已完成,并且仍想等待固定的秒数,请使用 performSelector:withObject:afterDelay: 例如在给定延迟后调用方法;对于您的示例,此方法通常会关闭您的 alertView 并调用 popToRootViewControllerAnimated 方法。

    其他选项是为此使用 NSTimer,但 performSelector:withObject:afterDelay: 应该很容易使用。

    【讨论】:

    • 嗨,阿里,感谢您的回答。也感谢您指出我的错误。我已经使用上面的 Deepak 代码满足了要求。谢谢你和迪帕克。 :)
    • 感谢您的反馈。但更喜欢投票给答案,而不是使用 cmets 来表示感谢。例如,如果我的答案对您有用,您可以投票支持(单击我的答案左侧的灰色箭头),如果 Deepak 的答案也有帮助,您也可以这样做。此外,如果我们的某个帖子确实完全回答了您的问题,请考虑通过单击答案旁边的 √ 标记来验证最佳答案(从而将您的问题也标记为已解决)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多