2013-07-04 3 views
1

상쾌하지 좀 재사용과 UICollectionViewFlowLayout와 collectionView 있습니다. Becouse 나는 이것이 문제라고 생각한다. 목록에서 눈에 보이지 않는 요소로 스크롤하면 "오래된"elemnts를 먼저 볼 수 있었고 새로운 요소를 볼 수있었습니다. 왜 그런가요? 내 tryToShow 메서드는 기본적으로 다운로드 관리자입니다. 나는 그것을 논평에서 설명하려고 노력한다. 여기CollectionView 버튼/이미지 및 시간 문제

-(void)tryToShow { 
    NSString* imageFile = self.linkToImageFileSavedOnDisk //This is my local file saved in documentsDirectory. 

    if([[NSFileManager defaultManager] fileExistsAtPath:imageFile]) { 
     [self.overlayButton setBackgroundImage:[UIImage imageWithContentsOfFile:imageFile] forState:UIControlStateNormal]; 
     [self disableActIn]; //Here i stop and remove activity indicator. 
    } else { 
     // Here i fire NSURLConnection and try to download. When NSURLConnection finished i put image to overlayButton. 
    } 
} 

위임 방법 : 다음 overlayButton가 UICollectionViewCell에 버튼이기

-(void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    //Here do some stuff to convert Data into UIImage... not important. 
    [self.overlayButton setBackgroundImage:object forState:UIControlStateNormal]; 
} 

여기서 코드이다. 나는 그것을위한 커스텀 클래스를 가지고있다.

알아낼 수 없습니다. 스크롤 후 indexPath.row (예 : 1)의 이미지를 표시하는 방법은 무엇입니까? 새로운 이미지가 성공적으로 다운로드 된 직후 이미지가 새로운 이미지로 바뀌지 만, 늦어집니다.

+0

여기에서 "dequeueReusableCellWithReuseIdentifier"메서드를 사용할 수 없습니다. 요청 응답을 받기 전에 셀을 dequeue하면 잘못된 셀을 새로 고칩니다. 각 셀마다 고유 식별자를 사용해야합니다. – lucaslt89

+0

그래서'dequeue' 대신에 무엇을 사용할 수 있습니까? – Kuba

+0

일반적으로 더 나은 UX를 얻으려면 셀을 캐시해야하므로 사용자가 다운 된 다음 셀로 돌아 오면 요청을 다시 기다릴 필요가 없습니다. 그래서, 내가 그럴 경우 매번 새로운 셀을 만들고, indexPath가 키이고 값이 셀인 사전에 셀을 저장합니다. 그런 다음 캐시에서 셀을로드하거나 캐시되지 않은 경우 새 셀을 만듭니다. – lucaslt89

답변

1

OP 언급에서 문제는 사용자가 backgroundImage을 너무 늦게 설정 한 것으로 보입니다. 그래서 나는이 수정을 시도 할 것 :

먼저
  1. , 분명 당신의 셀을 새 값을 설정하기 전에. 셀을 다시 사용하기 때문에 이전 값 (텍스트 및 이미지)이 셀 하위 뷰에 계속 남아 있습니다. 이 값을 nil로 설정하면 셀이 지워집니다.

  2. 어쩌면 더 이상 필요하지, 너무 늦게 결과를 얻을 수 있기 때문에, 검증 또는 이미지 요청에서 결과를 무효화하는 메커니즘을 구현합니다. 최악의 경우 데이터와 더 이상 통신하지 않는 이미지를 설정할 수 있습니다. 다운로드 한 이미지를 설정하기 전에이 이미지가 현재 표시된 데이터와 일치하는지 확인해야합니다.

  3. 당신이 세포의 수가 많은 경우 이전의 이미지 요청을 시작 조금 잠깐, 당신은 사용자가 빠르게 컬렉션을 스크롤 할 때, 당신은 표시되지 않을 수도 이미지에 대한 요청을 많이 시작할 수 있다고 생각한다. 새 요청을 시작하기 전에 조금 기다렸다가 셀이 다시 재사용되었는지 확인하면이 동작을 피할 수 있습니다.

  4. NSURLRequest를 사용하고 cachePolicy 특성을 NSURLRequestReturnCacheDataElseLoad으로 구성하십시오. 이렇게하면 이미지에 대한 응답이 저장되므로 이미지를 저장하고 명시 적으로 이미지를 저장하고 존재 여부를 확인할 필요가 없습니다.

+0

고맙습니다 - 대답은 저의 실수이고 해결 된 문제입니다. 나는 너에게 최대한 빨리 현상금을 줄 것이다. – Kuba

0

나는 당신이 웹 요청을 시작 어디 다른 절에서 전무로 self.overlayButton의 배경 이미지를 설정할 필요가 있다고 생각합니다. 셀에 이미지가 표시되지 않습니다

[self.overlayButton setBackgroundImage:nil forState:UIControlStateNormal]; 

그 방법은 그것에 이미 때 사용자가 스크롤을로드. 또는 충분히 빠르게로드하지 않는 경우에는 (대신) collectionView:didEndDisplayingCell:forItemAtIndexPath: 대리자 메서드에서 배경 이미지를 nil로 설정할 수 있습니다.

그러나 문제는 tryToShow이 호출 될 때마다 중복 된 NSURLConnection 개체를 생성한다는 것입니다. 즉, 사용자는 아래로 스크롤 한 다음 상단의 셀을 다시 방문합니다.

@ lucaslt89가 제안했듯이, 기본 dequeuing을 사용하는 대신 셀 사전을 만들 수 있습니다. 이렇게하면 셀의 URL 연결 객체에 대한 속성이 있는지 확인하고 새 객체를 시작하기 전에이를 확인하십시오.

또는보기 컨트롤러에서 만든 NSURLConnection 개체의 사전을 만들고 웹 요청 코드를보기 컨트롤러로 옮길 수 있습니다. 웹 요청이 필요한 경우보기 컨트롤러는 사전에 먼저 웹 요청이 실행되고 있는지 확인합니다. 요청이 완료되면 요청 개체가 사전에서 제거됩니다. 이것은 셀이 자체 데이터를 생성하는 책임이 없으므로 바람직한 방법입니다. UICollectionView에서 셀은 신속하게 역할을 변경해야하며 실제 셀이 거의없는 경우 특정 셀을 일부 데이터와 연결하는 것은 현명하지 않습니다.

어느 쪽이든, 당신은 같은 이미지 여러 URL 요청을 만들지 않도록합니다.

희망이 도움이됩니다.