비슷한 문제가 발생했지만 매우 다른 해결책을 찾았습니다.
가로 스크롤이있는 UICollectionViewFlowLayout의 사용자 지정 구현을 사용하고 있습니다. 또한 각 셀에 대해 사용자 지정 프레임 위치를 만들고 있습니다.
내가 가진 문제는 [super layoutAttributesForElementsInRect : rect]가 실제로 화면에 표시되어야하는 모든 UICollectionViewLayoutAttributes를 반환하지 않는다는 것입니다. [self.collectionView reloadData]를 호출하면 일부 셀이 갑자기 숨김으로 설정됩니다.
내가 한 일은 지금까지 본 모든 UICollectionViewLayoutAttributes를 캐시 한 다음 표시되어야하는 항목을 포함하는 NSMutableDictionary를 만드는 것입니다.
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray * originAttrs = [super layoutAttributesForElementsInRect:rect];
NSMutableArray * attrs = [NSMutableArray array];
CGSize calculatedSize = [self calculatedItemSize];
[originAttrs enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * attr, NSUInteger idx, BOOL *stop) {
NSIndexPath * idxPath = attr.indexPath;
CGRect itemFrame = [self frameForItemAtIndexPath:idxPath];
if (CGRectIntersectsRect(itemFrame, rect))
{
attr = [self layoutAttributesForItemAtIndexPath:idxPath];
[self.savedAttributesDict addAttribute:attr];
}
}];
[self.savedAttributesDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSArray * cachedAttributes, BOOL *stop) {
CGFloat columnX = [key floatValue];
CGFloat leftExtreme = columnX;
CGFloat rightExtreme = columnX + calculatedSize.width;
if (leftExtreme <= (rect.origin.x + rect.size.width) || rightExtreme >= rect.origin.x) {
for (UICollectionViewLayoutAttributes * attr in cachedAttributes) {
[attrs addObject:attr];
}
}
}];
return attrs;
}
다음은 UICollectionViewLayoutAttributes가 올바르게 저장되고있는 NSMutableDictionary의 범주입니다.
#import "NSMutableDictionary+CDBCollectionViewAttributesCache.h"
@implementation NSMutableDictionary (CDBCollectionViewAttributesCache)
- (void)addAttribute:(UICollectionViewLayoutAttributes*)attribute {
NSString *key = [self keyForAttribute:attribute];
if (key) {
if (![self objectForKey:key]) {
NSMutableArray *array = [NSMutableArray new];
[array addObject:attribute];
[self setObject:array forKey:key];
} else {
__block BOOL alreadyExists = NO;
NSMutableArray *array = [self objectForKey:key];
[array enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *existingAttr, NSUInteger idx, BOOL *stop) {
if ([existingAttr.indexPath compare:attribute.indexPath] == NSOrderedSame) {
alreadyExists = YES;
*stop = YES;
}
}];
if (!alreadyExists) {
[array addObject:attribute];
}
}
} else {
DDLogError(@"%@", [CDKError errorWithMessage:[NSString stringWithFormat:@"Invalid UICollectionVeiwLayoutAttributes passed to category extension"] code:CDKErrorInvalidParams]);
}
}
- (NSArray*)attributesForColumn:(NSUInteger)column {
return [self objectForKey:[NSString stringWithFormat:@"%ld", column]];
}
- (void)removeAttributesForColumn:(NSUInteger)column {
[self removeObjectForKey:[NSString stringWithFormat:@"%ld", column]];
}
- (NSString*)keyForAttribute:(UICollectionViewLayoutAttributes*)attribute {
if (attribute) {
NSInteger column = (NSInteger)attribute.frame.origin.x;
return [NSString stringWithFormat:@"%ld", column];
}
return nil;
}
@end