2012-03-09 2 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 

다른 (비 해킹) 솔루션

덕분에 오신 것을 환영합니다 :-)에게도!

답변

0

, 그것은 소리 . iOS에서는 드로잉이 즉시 발생하지 않기 때문에 OS가 디스플레이를 업데이트 할 때까지 로그인을 연기하면 그릴 수 있습니다.

여기에 하나의 합리적인 해결책을 사용했습니다. 또 다른 (틀림없이 적은 해킹)은 -[self login]이 별도의 스레드에서 로그인을 생성하거나 비동기 메커니즘 (예 : NSURLConnection의 비동기 모드, 네트워크 요청을한다고 가정)을 사용하는 것입니다. 그런 다음 주 스레드가 신속하게 iOS에 제어권을 반환하고 상자가 표시됩니다.

Grand Central Dispatch를 사용하면 -[self login]이 백그라운드 스레드에 네트워크 코드를 배치하고 백그라운드 스레드가 완료되면 주 스레드를 다시 호출하도록 할 수 있습니다. 그러나 로그인 프로세스 중에 사용자 이벤트에 응답하려면이 문제가 발생할 수 있습니다.

비동기 적으로 NSURLConnection을 사용하고 작업이 완료되었을 때 대리인이 다시보고하도록 설정하는 것이 가장 좋은 방법 일 수 있습니다. 사용자가 로그인 프로세스 중에 NSURLConnection을 취소하는 작업을 수행 할 수 있으므로 그것을 요청하십시오.

0

방법에 대해 : 문제가 4 항목을 나타내는입니다 [self login] 마감은 로그인 절차가 약간의 시간이 걸립니다 때까지 그려되지 않는다는 것입니다 같이 당신의 설명을 바탕으로

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

예, 알림은 어떤 식 으로든 존재합니다. 레이블은 실행 루프의 다음 반복 중에 그려집니다. 그래서 사용 예를 들어, 다음 실행 루프 반복의 끝에서 당신의 login를 수행 performSelector:afterDelay:0 아니면

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

를 사용하지만)이 타이머와 dispatch_queues 대 렌더링의 실행 순서에 따라 달라집니다.타이머 실행 전에 렌더링이 발생하면 모두 설정됩니다.

그리고 b) 주 스레드를 차단하지 마십시오. 백그라운드 스레드/동시 대기열에서 로그인을 시도하거나 사용중인 경우 주 스레드에서 비동기 적으로 수행하십시오 (예 : NSURLConnection).

관련 문제