Tôi đang cố gắng sao chép một kịch bản mà tôi có một giao diện bộ sưu tập ở phía trên cùng của hàng đầu tiên của giao diện bộ sưu tập, sau đó xem phần tiêu đề (đối với indexPath.section == 1) dính vào khung nhìn tiêu đề mà không bị chồng chéo hoặc đi bên dưới nó.UICollectionView Mục Tiêu đề Gắn vào một Y nào đó
Tôi đã triển khai bố cục tùy chỉnh để làm cho tiêu đề dính. Nhưng tôi không thể làm cho nó dính vào chế độ xem tiêu đề (vì vậy sau 'chiều cao' origin.y +), nó sẽ nằm ở đầu chế độ xem bộ sưu tập.
Dưới đây là cấu trúc của tôi IB:
với cách bố trí tùy chỉnh liên kết lên:
Đây là kịch bản lý tưởng:
Trước khi di chuyển:
012.351.Sau khi di chuyển:
Dưới đây là mã của tôi:
@implementation LLCollectionCustomFlowLayout
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
for (NSUInteger idx=0; idx<[answer count]; idx++) {
UICollectionViewLayoutAttributes *layoutAttributes = answer[idx];
if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell) {
[missingSections addIndex:layoutAttributes.indexPath.section]; // remember that we need to layout header for this section
}
if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
[answer removeObjectAtIndex:idx]; // remove layout of header done by our super, we will do it right later
idx--;
}
}
// layout all headers needed for the rect using self code
[missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
if (layoutAttributes != nil) {
[answer addObject:layoutAttributes];
}
}];
return answer;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionView * const cv = self.collectionView;
CGPoint const contentOffset = cv.contentOffset;
CGPoint nextHeaderOrigin = CGPointMake(INFINITY, INFINITY);
if (indexPath.section+1 < [cv numberOfSections]) {
UICollectionViewLayoutAttributes *nextHeaderAttributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:[NSIndexPath indexPathForItem:0 inSection:indexPath.section+1]];
nextHeaderOrigin = nextHeaderAttributes.frame.origin;
}
CGRect frame = attributes.frame;
if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
frame.origin.y = MIN(MAX(contentOffset.y, frame.origin.y), nextHeaderOrigin.y - CGRectGetHeight(frame));
}
else { // UICollectionViewScrollDirectionHorizontal
frame.origin.x = MIN(MAX(contentOffset.x, frame.origin.x), nextHeaderOrigin.x - CGRectGetWidth(frame));
}
attributes.zIndex = 1024;
attributes.frame = frame;
}
return attributes;
}
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
return attributes;
}
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
return attributes;
}
@end
Cảm ơn câu trả lời của bạn. Nó không hoạt động mặc dù. Sau khi sửa hai cảnh báo trình biên dịch (prevHeaderMaxY và prevHeaderMaxX nên là CGFloats), tiêu đề không dính vào đầu nữa. Tôi tin rằng điều này là do sự vắng mặt của một phần [0] tiêu đề. Vì nó là nil, nó không thể tìm thấy điểm gắn bó. – jonypz
Tôi đã đặt tiêu đề đầu tiên trở lại và nó vẫn không hoạt động. Bây giờ tiêu đề không còn dính nữa. – jonypz
Cố gắng sử dụng 'UICollectionViewLayoutAttributes * prevHeaderAttributes = [self layoutAttributesFor ...' thay vì 'UICollectionViewLayoutAttributes * prevHeaderAttributes = [super ...'. Cuộc gọi siêu sẽ không trả về các thuộc tính chính xác của giá trị cũ. tiêu đề – sgl0v