2013-05-18 20 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之間的主要區別