2012-09-24 3 views
6

사용자 지정 레이아웃을 사용하여 UICollectionView를 설정하려고합니다. 각 CollectionViewCell의 내용은 이미지입니다. 전체적으로 수천 개의 이미지가 있고 특정 시간에 140-150 개의 이미지가 표시됩니다. 액션 이벤트에서 잠재적으로 모든 셀이 위치와 크기로 재구성됩니다. 목표는 현재 performBatchUpdates 메소드를 사용하여 움직이는 모든 이벤트에 애니메이션을 적용하는 것입니다. 이로 인해 모든 것이 애니메이션으로 표시되기 전에 엄청난 지연 시간이 발생합니다.performBatchUpdates의 UICollectionView 성능 문제

이번에는 내부적으로 layoutAttributesForItemAtIndexPath 메서드가 모든 단일 셀 (총 수천 개)에 대해 호출된다는 것을 알았습니다. 또한 cellForItemAtIndexPath 메서드는 실제로 화면에 표시 할 수있는 것보다 많은 셀에 대해 호출됩니다.

애니메이션의 성능을 향상시킬 수있는 방법이 있습니까?


기본적으로 UICollectionViewFlowLayout은 앱에서 실현시키고 싶은 디자인을 제공 할 수 없습니다. 여기에 우리의 코드 중 일부의 다음 RECT 내 allthe 요소 layoutAttributes을 설정하는 모든 요소를 ​​

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
RPDataModel *dm = [RPDataModel sharedInstance]; //Singleton holding some global information 
NSArray *plistArray = dm.plistArray; //Array containing the contents of the cells 
NSDictionary *dic = plistArray[[indexPath item]]; 
RPCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath]; 
cell.label.text = [NSString stringWithFormat:@"%@",dic[@"name"]]; 
cell.layer.borderColor = nil; 
cell.layer.borderWidth = 0.0f; 
[cell loadAndSetImageInBackgroundWithLocalFilePath:dic[@"path"]]; //custom method realizing asynchronous loading of the image inside of each cell 
return cell; 
} 

layoutAttributesForElementsInRect 반복은. 세포의 수를 정의되는 경우 결과가 거의없이 동일하다 레이아웃에

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { 
NSMutableArray* attributes = [NSMutableArray array]; 
RPDataModel *dm = [RPDataModel sharedInstance]; 
for (int i = 0; i < dm.cellCount; i++) { 
    CGRect cellRect = [self.rp getCell:i]; //self.rp = custom object offering methods to get information about cells; the getCell method returns the rect of a single cell 
    if (CGRectIntersectsRect(rect, cellRect)) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[dm.relevanceArray[i][@"product"] intValue] inSection:0]; 
     UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 
     attribute.size = cellRect.size; 
     attribute.center = CGPointMake(cellRect.origin.x + attribute.size.width/2, cellRect.origin.y + attribute.size.height/2); 
     [attributes addObject:attribute]; 
    } else if (cellRect.origin.x > rect.origin.x + rect.size.width && cellRect.origin.y > rect.origin.y + rect.size.height) { 
     break; 
    } 
} 
return attributes; 
} 

가 변경 : 첫 번째 셀에 대한 문 휴식은 RECT의 오른쪽 하단 모서리에 의해 정의 된 경계를지나 인 layoutAttributesForElementsInRect가 제한되어 있거나 제한되어 있습니다. 제한되지 않은 경우 시스템이 모든 셀의 레이아웃 속성을 가져 오거나 제한된 경우 모든 누락 된 셀에 대해 layoutAttributesForElementAtIndexPath 메소드를 호출합니다. 전반적으로 모든 단일 셀의 속성이 어떻게 든 사용되고 있습니다. 코드를 보지 않고

-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { 
RPDataModel *dm = [RPDataModel sharedInstance]; 
UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 
CGRect cellRect = [self.rp getCell:[dm.indexDictionary[@(indexPath.item)] intValue]]; 
attribute.size = cellRect.size; 
attribute.center = CGPointMake(cellRect.origin.x + attribute.size.width/2, cellRect.origin.y + attribute.size.height/2); 
return attribute; 
}  
+0

UICollectionViewLayout에서 코드를 게시하십시오. –

답변

3

, 내 생각 엔 당신의 layoutAttributesForElementsInRect 방법은 컬렉션의 모든 항목을 통해 반복되어 있으며, 즉, 차례로, 다른 방법을 통해 소위 얻을 원인이 무엇. layoutAttributesForElementsInRect는 layoutAttributesForItemAtIndexPath를 호출해야하는 항목에 대해 화면에 표시되는 항목에 대한 힌트를 제공합니다. 즉, 전달되는 CGRect입니다.

성능 문제가 될 수 있습니다. 즉, 사용자 지정 레이아웃을 조정하여 업데이트중인 항목에 대해 스마트하게 처리 할 수 ​​있습니다.

다른 문제는 일반적으로 애니메이션 성능과 관련이 있습니다. 조심해야 할 것은 합성 작업이 진행되는 경우입니다. 이미지가 불투명한지 확인하십시오. 또 다른 한 가지는 이미지에 그림자를 사용하는 경우 애니메이션에 비용이들 수 있습니다. 그림자의 애니메이션 성능을 향상시키는 한 가지 방법은 이미지 크기를 조정할 때 shadowPath 값을 설정하는 것입니다. 그림자가 있으면 그 작업을위한 코드를 알려주고 게시하십시오.

+0

layoutAttributesForElementsInRect에 주어진 rect의 안쪽에있는 모든 요소를 ​​반복하기 만하면됩니다. 여전히 시스템은 rect 외부의 모든 셀에 대해 layoutAttributesForItemAtIndexPath 메소드를 호출합니다.이미지의 경우, 우리는 전혀 그림자를 사용하지 않으며 이미 불투명합니다. 하나의 문제는 한 번에 볼 수있는 뷰의 양 (약 140) 일 수 있습니다. –

+0

코드를 게시하면 도움이됩니다. 하나의 제안은 디버깅 목적으로 내장 된 UICollectionViewFlowLayout을 사용하여 동일한 콜렉션 뷰를 구현하고 사용자 정의 뷰에서 사용중인 것과 유사한 매개 변수를 제공합니다. UICollectionViewFlowLayout이 중요한 방식으로 재구성되도록하는 이벤트를 트리거하고 애니메이션이 더 좋은지 확인합니다. –

+0

FYI, 애플은 마침내 CollectionViews에 대한 샘플 코드 프로젝트를 게시했습니다. 불행히도, 이것은 가장 우스꽝스럽게 간단한 구현입니다. 커스텀 레이아웃이 없습니다. 정말보아야 할 코드입니다. –

0

이는 헤더보기가 있지만 이미 셀이없는 섹션에 셀을 추가하려고 시도한 것으로 나타납니다.

오류 메시지는 기념비적으로 도움이되지 않으며이를 추적하는 데 몇 시간의 노력이 필요했습니다.