2012-03-09 23 views
0

私のアプリへのログインにピンスクリーンを使用しています。ピンスクリーンは、4つのラベルと隠れたテキストフィールドで構成されています。ユーザーがキーパッドを使用してテキストを入力すると、記号でラベルを更新します。これは正常に動作しますが、ログインが始まる前に最後のラベルが実際に更新されず、ログイン処理が完了しても空のままになります。iosでラベルが更新された後にアクションを実行します

これらはコードの関連するビットです:

//an observer has been added elsewhere 
- (void)textDidChange:(NSNotification *)notification 
{ 
    UITextField *field = [notification object]; 
if (field == inputField) 
    { 
    NSString *newText = field.text;  
    if ([newText length] <= pinLength) [self updatePINDisplay]; 
    } 
} 


-(void)updatePINDisplay 
{ 
    if ([pinText length] > pinLength) return; 

    for (NSInteger ii = 0; ii < [pinText length]; ii++) 
    { 
     UILabel *label = [pinFields objectAtIndex:ii]; 
     [label setText:@"x"]; 
    } 

    for (NSInteger ii = [pinText length]; ii < pinLength; ii++) 
    { 
    UILabel *label = [pinFields objectAtIndex:ii]; 
    [label setText:[NSString string]]; 
    } 

    if ([pinText length] == pinLength) [self login]; 
} 

[自己ログイン]は、最後のピンのラベルが更新される前に起こる他のプロセスを起動するので、最後のボックスがまだある間、ログインが発生したため、問題が発生します空の。

私は

[self performSelector:@selector(login) withObject:nil afterDelay:0.1] 

[self login] 

を置き換えることによって、問題を回避してきましたが、私は、任意の時間遅延を好きではありません。私は、ラベルが描かれた後に私のログインコードを起動するために使える代理メソッドがあったと思っていました。ような何か:

-(void)labelDidGetDrawn 

その他(非ハック)ソリューションを:-)

おかげも歓迎されます!問題は、第四項目が[self login]終了後まで描かれないということであるように、あなたの記述に基づいて

[label setNeedsDisplay:YES]; 
if ([pinText length] == pinLength) [self login]; 

答えて

0

、それはログイン手順は、いくつかの時間がかかることを示しているこれ、聞こえる:についてどのように

0

。 iOSでは、描画が即座に行われるわけではありません。なぜなら、OSに表示を更新する機会があるまで、ログインを延期する場合に限り描画を取得するからです。

ここでは妥当な解決法を1つ使用しました。あなたの-[self login]が別のスレッドでログインを起動させるか、少なくともNSURLConnectionの非同期モード(ネットワーク要求を行っていると仮定して)のような非同期メカニズムを使用することが、(おそらくハックの少ない)ものです。メインスレッドはすぐにコントロールをiOSに戻し、ボックスが描画されます。

グランドセントラルディスパッチでは、-[self login]にバックグラウンドスレッドにネットワークコードを置き、バックグラウンドスレッドが完了したらメインスレッドにコールバックさせることで、ほとんどのことを行うことができます。ただし、ログイン処理中にユーザーイベントに応答する場合は、この問題が発生する可能性があります。

NSURLConnectionを非同期で使用し、操作が完了したときに代理人が返信するように設定するのがおそらく最良の選択です。これは、ユーザーがログインプロセス中にNSURLConnectionをキャンセルする操作を行うためですそれを要求する。

0

はい、その通知は、ある意味で存在します。ラベルは、実行ループの次の反復中に描画されます。だからあなたのlogin

dispatch_async (dispatch_get_main_queue(), ^{ [self login]; }); 

を使用してperformSelector:afterDelay:0または多分を使用して、たとえば、次の実行ループ反復の終了時に行う。しかしa)は、これはタイマーとdispatch_queues対レンダリングの実行順序に依存します。タイマーを実行する前にレンダリングが行われると、すべて設定されます。

そして、b)メインスレッドをブロックしないでください。バックグラウンドスレッド/並行キューでログインを実行するか、メインスレッドで非同期に実行してください(例:NSURLConnection)。

関連する問題