이미지를 비동기 적으로 다운로드하고 UITableView에 표시하고 있습니다. 이미지가 다운로드되는 동안 해당 테이블 행에 UIProgressView가 표시되어야합니다. 다운로드가 완료되면 진행보기가 실제 이미지로 바뀝니다.UIProgressView 표시기가 올바른 "진행률"로 업데이트되지 않습니다.
내 테이블보기에서 UITableViewCell에서 서브 클래 싱 된 ProgressTableViewCell이라는 사용자 지정 셀을 사용하고 있습니다. 그것은 UIProgressView IBOutlet을 가지고 있습니다.
NSURLConnection에서 NSOperation을 만들고 NSOperationQueue에 추가했습니다. 대리인의
didReceiveData
메서드를 호출 할 때, 알림이
reloadRowsAtIndexPaths
테이블보기의 방법으로 해당 테이블의 행을 업데이트 내 테이블 뷰 컨트롤러에 게시됩니다. 내 cellForRowAtIndexPath는 다시로드 된 행에 대해 다음 작업을 수행합니다 내가 주 스레드에서 진행보기를 업데이트하고
- (void)updateProgressView :(NSMutableDictionary *)userInfo
{
ProgressTableViewCell* cell = [userInfo valueForKey:@"cell"];
NSNumber* progress = [userInfo valueForKey:@"percentage"];
[cell.progressView setProgress:progress.floatValue ];
NSLog(@"Progress after update: %f", cell.progressView.progress);
}
처럼
는
ProgressTableViewCell *cell = (ProgressTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"ProgressCell"];
float received = [[downloadInfo objectForKey:@"receivedBytes"] floatValue];
float total = [[downloadInfo objectForKey:@"totalFileSize"] floatValue];
NSNumber* percentage= [NSNumber numberWithFloat:received/total];
NSMutableDictionary* userInfo = [[NSMutableDictionary alloc] init];
NSLog(@"percentage %f", percentage.floatValue);
[userInfo setObject:cell forKey:@"cell"];
[userInfo setObject:percentage forKey:@"percentage"];
[self performSelectorOnMainThread:@selector(updateProgressView:) withObject:userInfo waitUntilDone:NO];
NSLog(@"received: %@", [downloadInfo objectForKey:@"receivedBytes"]);
NSLog(@"Progress: %f", cell.progressView.progress);
return cell;
updateProgressView 방법을보고 난 YES로 이에 waitUntilDone 설정 시도 아무 소용이. 내 진행 뷰는 영점에 머물러 있습니다. 때로는 디버깅 할 때 진행 표시기에 약간의 변화가있어서 타이밍 문제 일 수 있다고 생각할 수도 있습니다. 그러나 그것을 해결하는 방법?
편집 : 여기에있는 NSURLConnection 위임의 didReceiveData 방법입니다 :
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_responseData appendData:data];
NSNumber* bytes = [NSNumber numberWithUnsignedInt:[data length]];
NSLog(@"received bytes:%d", [bytes intValue]);
NSMutableDictionary* userInfo = [[NSMutableDictionary alloc] init];
[userInfo setObject:_responseId forKey:@"responseId"];
[userInfo setObject:bytes forKey:@"receivedBytes"];
[self fireNotification: [NSNotification
notificationWithName:@"DidReceiveData"
object:self userInfo:userInfo]];
}
- (void)fireNotification :(NSNotification *)aNotification
{
[[NSNotificationCenter defaultCenter] postNotification:aNotification];
}
그리고 여기에 통지 도착 내보기 컨트롤러의 방법입니다 :
-(void) dataReceived:(NSNotification *)notification {
NSNumber* responseId = [[notification userInfo] objectForKey:@"responseId"];
NSNumber* bytes = [[notification userInfo] objectForKey:@"receivedBytes"];
NSMutableDictionary* downloadInfo = [self getConnectionInfoForId:responseId];
NSLog(@"received bytes:%ld for response %@", [bytes longValue], responseId);
NSNumber* totalBytes = [NSNumber numberWithInt:([bytes longValue] + [[downloadInfo objectForKey:@"receivedBytes"] longValue]) ];
[downloadInfo setObject:totalBytes forKey:@"receivedBytes"];
float received = [[downloadInfo objectForKey:@"receivedBytes"] floatValue];
float total = [[downloadInfo objectForKey:@"totalFileSize"] floatValue];
[downloadInfo setObject:[NSNumber numberWithFloat:received/total] forKey:@"progress"];
[self reloadRowForResponse:responseId];
}
나는 또한 내 cellForRowAtIndexpath 방법에 전무 체크를 추가 한을 권장 사항 :
ProgressTableViewCell *cell = (ProgressTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"ProgressCell"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ProgressCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
float received = [[downloadInfo objectForKey:@"receivedBytes"] floatValue];
float total = [[downloadInfo objectForKey:@"totalFileSize"] floatValue];
NSNumber* percentage= [NSNumber numberWithFloat:received/total];
NSMutableDictionary* userInfo = [[NSMutableDictionary alloc] init];
NSLog(@"cell:%@", cell);
NSLog(@"percentage %f", percentage.floatValue);
[userInfo setObject:cell forKey:@"cell"];
[userInfo setObject:percentage forKey:@"percentage"];
[self performSelectorOnMainThread:@selector(updateProgressView:) withObject:userInfo waitUntilDone:NO];
return cell;
알림을 처리하는 데 사용하는 대리자 메서드 및 메서드를 게시 할 수 있습니까? 내 생각 엔 알림 경로와 다운로드 정보를 알림 처리기에서 사용할 수 있다면 매번 테이블보기를 다시로드하는 대신 진행률보기를 업데이트해야합니다. –
나는 Joe라는 방법을 게시했다. 위의 내용은 EDIT에서 볼 수 있습니다. 문제는 다운로드중인 각 이미지에 대해 진행률보기가 있으므로 테이블 뷰의 데이터 소스 대리자 메서드 내에서 업데이트를 수행하는 이유입니다. – ganime