2013-05-18 21 views
0

我对ios有点新,但是我已经能够混淆了......直到现在。我有一个登录页面的应用程序。我做的第一件事是创建一些空的视图控制器,并将它们粘在故事板上。我有一个LoginViewController,带有一些用于userId和密码的文本字段以及一个登录按钮。计划是如果您成功登录,您将被带到一个TabViewController。现在这是开箱即用的。我删除了用它创建的两个视图控制器,并用两个NavigationControllers替换它们。手动继续不正常转换

只是为了测试我从登录按钮切换到TabViewController的一切。一切正常。意见来了。所有开箱即可使用。

下一步我试图模拟一个实际的登录。由于我必须通过Web服务调用来完成此任务,因此我认为它需要是异步的。我删除了我为登录按钮添加的初始segue,并从该按钮向我的LoginViewController添加了一个IBAction。我也从我的LoginViewController到TabViewController增加了一个手动赛格瑞,我把它命名为“loginSegue”

这里是我的代码至今:

- (IBAction)login:(id)sender { 
[Decorator showViewBusyIn:self.aView 
      scale:1.5 
     makeWhite:NO]; 

self.clientIdText.enabled = NO; 
self.userIdText.enabled = NO; 
self.passwordText.enabled = NO; 
UIButton* loginBtn = sender; 

loginBtn.enabled = NO; 
[Decorator showViewBusyIn:self.aView 
      scale:2.0 
     makeWhite:NO]; 

self.operation = [[NSInvocationOperation alloc] 
      initWithTarget:self 
        selector:@selector(doLogin) 
       object:nil]; 
self.queue = [[NSOperationQueue alloc] init]; 
[self.queue addOperation:self.operation]; 
} 

-(void)doLogin{ 
    [NSThread sleepForTimeInterval:1]; 
    [Decorator removeBusyIndicatorFrom:self.aView]; 
// this is where I will eventually put the login code... 
    [self performSegueWithIdentifier:@"loginSegue" sender:self]; 
} 

我把电话给sleepForTimeInterval模拟等待Web服务调用完成。我将在稍后删除它。装饰者的东西只是显示和删除活动指标视图。

当我这样做了segue的作品,但与登录视图控制器相关的视图保留在屏幕上。换句话说,TabViewController显示出来。第一项被选中。 NavigationController显示出来,但与其关联的VC及其包含的视图不出现。来自LoginViewController的视图停留在那里。

由于所有导航都正常工作,当我把登录按钮上的segue我认为它与调用操作有关。无论是或者不知何故我的视图或视图控制器层次结构正在变得混乱。

任何想法,我做错了什么? 这是做登录的好方法吗?

任何帮助是非常赞赏, 纳特

+0

我真的不明白为什么,但问题是,我打电话给performSegueWithIdentifier:发件人:从主线程以外的线程。如果我强制在主线程上发生呼叫,我的segue可以正常工作。我用以下代码替换了执行SegueWithIdentifier:sender的调用:[self performSelectorOnMainThread:@selector(exeOnMainThread :) withObject:self waitUntilDone:NO]; exeOnMainThread只是调用performSegueWithIdentifer:发件人: 所以我得到它的工作,但我仍然想知道这是一个很好的方式来做登录。 –

回答

0

对于这种操作,使用GCD可以更容易。你会做这样的事情:

- (void)doLogin 
{ 
    dispatch_queue_t loginQueue = dispatch_queue_create(“login”, NULL); 
    dispatch_async(loginQueue, ^{   
     // this is where you will eventually put the login code... 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [Decorator removeBusyIndicatorFrom:self.aView]; 
      [self performSegueWithIdentifier:@"loginSegue" sender:self]; 
     }); 
    }); 
} 

而在你-(IBAction)login:(id)sender您只需拨打[self doLogin]代替

self.operation = [[NSInvocationOperation alloc] 
            initWithTarget:self 
             selector:@selector(doLogin) 
              object:nil]; 
self.queue = [[NSOperationQueue alloc] init]; 
[self.queue addOperation:self.operation]; 

检查这个question,其中简要介绍了什么是GCD和NSOperationQueue之间的主要区别