2011-03-25 4 views
1

서버에서받는 문자열에서 카운트 다운되는 타이머를 만들어야합니다. 문자열은 남은 총 시간 (초)을 출력합니다.시간 계산이 점점 더 잘못된 결과를 내고 있습니다.

나는이 코드를 사용하고 있습니다. 처음 숫자를 올바르게 계산하고 카운트 다운하지만 분이 문제입니다.

편집 - 실제 순간마다 1 분씩 계산이 올라갑니다. 그러나 나는 왜이 일을하는지 이해하지 못합니다.

- (무효) showTimmer (ID) 보낸 사람 {

//get total amount of seconds 

NSString *timeRaw = [ArrayFromServer objectAtIndex:1]; 
NSArray *timeArr = [timeRaw componentsSeparatedByString:@","]; 
timetoInt = [timeArr objectAtIndex:0]; 
int time1 = [timetoInt intValue]; 

//set the second countdown 

NSDate* now = [NSDate date];  
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 

NSDateComponents *dateComponents = [gregorian components:(NSSecondCalendarUnit) fromDate:now]; 

NSInteger seconds = time1 - [dateComponents second]; 

[gregorian release]; 

// do the hours days maths 

int hour = (seconds/3600); 
seconds -= hour * 3600; 
int minute = (seconds/60); 
seconds -= minute * 60; 
int second = seconds; 

//set the labels 

countdownLabel.text = [NSString stringWithFormat:@"%02dH %02dM %02ds", hour, minute, second]; 

답변

1

당신은 나사를 드라이브에 펜치를 사용하고 있습니다. NSDateComponentsseconds 방법은 당신이 보였다 경우 시계에 표시되는 것입니다 무엇을 제공합니다 NSDate으로 표시되는 초침에서 예로들 수 있습니다. 예를 들어,이 형식은 UTC 토요일 2011 년 3 월 26 일 02:52:04입니다. [NSDate date]을 얻은 경우 NSDateComponents으로 바꿔서 seconds 나는 "4"를 얻을 것입니다. 잠깐 후에 다시 "5"라고하면, "59", "0"을 얻을 것입니다.

직접 확인할 수 있습니다. 당신의 타이머 방법에 넣고 :

NSInteger dcSecond = [dateComponents second]; 
NSLog(@"%d", dcSecond); 

그래서 실제 시계의 분 동안 틱마다 남은 시간을 당신의 계산 :

NSInteger seconds = time1 - [dateComponents second]; 

time1에서 0을 빼고 다시 time1 제공합니다. 그래서 당신은 문제가 있습니다.

해결 방법은 캘린더 내용을 덤프하고 CFAbsoluteTimeGetCurrent()을 사용하는 것입니다. (당신이 원하는 경우 또는 바르에서) 먼저, 타이머의 사용자 정보에 시작 시간을 넣어 :

NSInteger startTime = [[timer userInfo] integerValue]; 
NSInteger currTime = (NSInteger)CFAbsoluteTimeGetCurrent(); 
NSInteger elapsedTime = currTime - startTime; 
NSInteger duration = time1 - startTime; 
//NSInteger seconds = time1 - [dateComponents second]; 
NSInteger remaining = duration - elapsedTime; 

int hour = remaining/3600; 
... 

:

[NSTimer scheduledTimer... 
     // The function returns CFAbsoluteTime, which is a 
     // typedef'd double but you're already working with 
     // integers, so use a cast 
      userInfo:[NSNumber numberWithInteger:(NSInteger)CFAbsoluteTimeGetCurrent()] 
       ...]; 

그런 다음 남은 시간 당신의 계산 (당신이 seconds 호출 변수를 변경

* : 음, 방법이긴하지만 아마도 가장 좋은 것 같아요.

+0

또 다른 옵션은 시작 시간을 NSDate로 저장 한 다음 NSInteger elapsedTime = (NSInteger) [startDate timeIntervalSinceNow]; –

+0

을 수행하는 것입니다.이 작업은 완벽하게 작동합니다. – jaggi

+0

네, NSDateComponents가 무엇을하는지 알기 전까지는 반올림 오류라고 생각했습니다. 그 클래스와 그것의 동료들에 관한 문서들은 확실히 간결한 편입니다. (개인적으로는 [NSCalendar-firstWeekday'] (http://developer.apple.com.덧붙여서, 당신은'double's를 사용하려고 시도 할 것입니다. 왜냐하면, 여러분은'double's를 시도 할 것입니다. 그것은'CF-'와'NS-''TimeInterval' 둘 다입니다. 그런 다음 필요에 따라'fmod','ceil' 및'floor'를 사용하십시오. 어쨌든, 내가 도울 수있어서 기뻐요! –

3

당신은 (당신이 모듈을 사용하는 이유 확실하지를) 다음 줄에 가기 전에 초 총 금액의 계산 시간을 뺄 필요가있다. 이런 식으로 뭔가를 (을 수정

int hour = (seconds/3600); 
seconds -= hour * 3600; 
int minute = (seconds/60); 
seconds -= minute * 60; 
int second = seconds; 

희망을 확인합니다.

+0

아니요. 문제는 그 순간이 아이폰 시뮬레이션에 올라 갔을 때입니다. 민트가 하나 올라 간다! 어떤 아이디어? – jaggi

+0

모듈화를 수행하는 것은 시간 파싱을 수행하는 데 매우 효과적인 방법입니다. 당신은 주변의 총 카운터 값을 유지해야 할 수도 있습니다. –

관련 문제