2014-09-21 2 views
1

새 데이터 소스에 따라 새 셀 크기를 설정하려면 컬렉션보기에서 데이터를 다시로드해야합니다. 처음부터 스크롤해야하기 때문에 애니메이션으로 처리하고 싶습니다. 모든 행에 1 개의 셀이 있습니다. 이 사용 그래서잘못된 이미지 위치를 유발하는 애니메이션으로 컬렉션보기 스크롤

:

[self.collectionView reloadData]; 
    [self.collectionView setContentOffset:CGPointZero animated:YES]; 

무슨 일이 그것을 시작으로 스크롤하고, 다시로드,하지만 그는 이미지 1에 올 때 내가 볼보다 더 많은 이미지를 빠르게 대체하고, 일부에 stopes이다 이미지는 첫 번째 셀에 속하지 않고 다른 셀에 속합니다. 난 애니메이션 (a nimated:NO)의 하지 발생하지 않고 시작 - 로 스크롤하면

. 애니메이션이 필요합니다. 이 문제의 원인은 무엇입니까?

편집 : 내가 내가 빠른 스크롤 할 때, 나는 그들이로드해야 최종 이미지로 전환하기 전에 자신의 세포에서 매우 빠르게 변화하는 이미지를 볼 수있는 유사한 문제를 볼 수 있습니다.

답변

1

문제는

그래서 작업이 비동기로의 빠르고 스크롤하면 1 개 셀에 대해이 작업을 파견하게됩니다 예를

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"YourCellId"]; 
    cell.image = nil; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     UIImage *image = [self imageForIndexPathRow:@(indexPath.row)]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      cell.image = image; 
     }); 
    }); 
    return cell; 
} 

을 보자, 세포가 재사용된다는 것입니다.

예를 들어 이름에 일부 셀 포인터 "ImageCell-1"을 지정하십시오.
빠른 스크롤을 시작하면 2 가지 작업이 전달됩니다.
첫 번째 작업이 "a.png"를로드하고 다운로드가 활성화되면 빠르게 스크롤하고 "ImageCell-1"이 (가) "b.png"로로드됩니다 ("a.png"는 아직로드 중입니다).

그래서 "a.png"가 다운로드를 완료하고 "ImageCell-1"로 설정되면 "b.png"를 완료하고 "ImageCell-1"로 설정됩니다.
(이 문제는 => "빠르게 스크롤하면 비슷한 문제가 나타날 수 있습니다.로드해야하는 최종 이미지로 바꾸기 전에 셀에서 매우 빠르게 변화하는 이미지를 볼 수 있습니다.")

또한 AFNetworking과 같은 "고급 라이브러리"를 사용할 때 대기열을 관리하고 동시성 다운로드를 사용할 수 있습니다. "b.png"가 다운로드를 완료하고이를 "ImageCell- 1 "을 입력하면"a.png "다운로드가 완료되고"ImageCell-1 "로 설정됩니다. 그러면 "b.png"대신 "a.png"가 표시됩니다.

해결책은 AFNetworking을 사용하는 경우 새 작업을 시작하기 전에 다운로드 작업을 취소하고 NSOperations를 유지하고 새 다운로드를 시작하기 전에 [operation cancelOperation];으로 전화하는 것입니다.

편집 :
이있는 NSURLConnection을 사용하는 경우 NSURLSession를 사용하는 현대적인 방법으로 전환해야 (요청 취소를 지원합니다).여기

나는이

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"YourCellId"]; 
    [cell loadImageFromPath:imagePath availableCache:self.cache]; 
    return cell; 
} 
+0

감사합니다. 문제를 잘 설명했지만 해결 방법이 분명하지 않습니다. 새 작업을 시작하기 전에 한 작업을 취소하면 일반 작업에 심각한 문제가 발생합니다. 그래서 프로그램이 시작될 때 셀 1 2 3 4를로드하려고 시도하는 것보다 보이지만 1이 시작될 때 2가 오면 취소하는 것보다 더 큽니까 ?? 나에게 명확하지 않다. 그리고 그런데, 나는 AFNetworking을 사용하지 않는다. 나는 그것을 좋아하지 않는다. 나는 당신이 다른 질문에서 나를 준 대답과 같은 이미지를로드한다 .. – Curnelious

+0

그리고 그런데, 나는 그 문제가 다른 것보다 설명 될 수 있다고 생각한다. 나는 같은 세포에 대해 2 가지 조작이 있다고 생각하지 않는다. 나는 내가 올라갈 때, 예를 들어 셀 6이 이미지 다운로드를 시작한다고 생각한다. cell6이 1 (재사용)이되고 6에서 이미지를 볼 때보 다. AFNetworking을 사용하지 않는다면 어떻게 될까? 너는 그 문제를 돌봐 줄거야? – Curnelious

+0

더 좋은 해결책은 스크롤러가 감속 할 때만 이미지를로드하는 것입니다. 데이터에 저역 통과 필터를 사용하는 것보다 좋습니다. – Curnelious

0
[UIView animateWithDuration:1.0 delay:0.0 options: UIViewAnimationOptionCurveEaseIn animations:^{ 
     [self.collectionView setContentOffset:CGPointZero animated:NO]; 
    } completion:nil]; 
}]; 
같은 셀에 문제

@interface MyCell() 

@property (strong, nonatomic) NSURLSessionDataTask *dataTask; 

@end 

- (void)loadImageFromPath:(NSString *)aPath 
      availableCache:(NSCache *)aCache 
{ 
    if (self.dataTask) { 
     [self.dataTask cancel]; 
    } 

    NSData *cache = [aCache objectForKey:aPath]; 
    if (cache) { 
     self.image = [UIImage imageWithData:cache]; 
     return; 
    } 
    self.dataTask = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:aPath] 
             completionHandler:^(NSData *data, 
                  NSURLResponse *response, 
                  NSError *error) 
           { 
            if (data) { 
             self.image = [UIImage imageWithData:data]; 
             self.dataTask = nil; 

             // Add to cache 
             [aCache setObject:data forKey:aPath]; 
            } 
           }]; 
    [self.dataTask resume]; 
} 

장소이 방법을 해결하는 작은 방법,

을 썼다 그리고 cellForRow에서 호출 한

나만의 애니메이션을 만들어보세요.

+0

고마워요,하지만 이것은 나쁜 해결책입니다. 문제를 해결하지 못했을뿐만 아니라, 이것을 시도하면 스크롤 뷰의 매우 원치 않는 동작을하게됩니다.제 대답을 확인해주세요. – Curnelious

+0

코드에서 어떤 일이 발생했는지 알지 못했습니다. 네가 해결했다고 들었어. –

1

제가 문제를 해결하거나 개선 된 사항이 많이 있다고 생각합니다. 당신이 인터넷에서 다운로드 시작할 때

글쎄, 당신의 블록을 태그 제공 :

- (void)downloadImageWithURL:(NSURL *)url AndTag:(int)Gtag completionBlock:(void (^)(BOOL succeeded, NSData *data,int tag))completionBlock 
{ 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
    int thetag=Gtag; 
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
    { 
     if (!error) 
     { 

      completionBlock(YES, data,thetag); 
     } 
     else 
     { 

      completionBlock(NO, nil,thetag); 
     } 
    }]; 
} 

보다, 셀이 현재 화면에있는 경우는없는 경우 다운로드 완료는, 우리가 확인됩니다 우리

[self downloadImageWithURL:url AndTag:(int)cell.tag completionBlock:^(BOOL succeeded, NSData *data,int tag) 
     { 

    BOOL isvisible=0; 
       for (iPhoneCostumCell *tcell in [self.collectionView visibleCells]) 
       { 
        if(tcell.tag==tag) 
        { 
         isvisible=1; 
         break; 
        } 
       } 

나는 이것이 좋은 해결책이라고 생각하며, 더 안정적인 것으로 생각한다. 또한 이미지를 찾지 못하면 다른 스레드에서 NSData 변환을 계속하지 않기 때문에 프로세서가 적게 작동합니다.

+0

내 편집 – l0gg3r

+0

을 참조하십시오. 문제를 해결할 수 있지만 다운로드 작업으로 인해 다른 셀이 일부 지연 후로드 될 수 있습니다 (이미 없음). – l0gg3r

관련 문제