Sto provando a replicare uno scenario in cui ho una vista insieme fino in cima, una vista titolo in cima alla prima riga della vista raccolta, poi una vista sezione intestazione (per indexPath.section == 1) che si attacca alla vista titolo senza sovrapposizioni o sottostanti.UICollectionView Section Header Attaccare ad un certo Y
Ho implementato un layout personalizzato, per rendere l'intestazione appiccicosa. Ma non riesco a farlo aderire alla vista del titolo (quindi dopo il suo 'origin.y + height), si attacca alla parte superiore della vista dell'insieme.
Ecco la mia struttura IB:
con il layout personalizzato legato fino:
Ecco lo scenario ideale:
prima di scorrere:
012.351.Dopo lo scorrimento:
Ecco il mio codice:
@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
Grazie per la risposta. Tuttavia non funziona. Dopo aver corretto due avvisi del compilatore (prevHeaderMaxY e prevHeaderMaxX dovrebbero essere CGFloats), l'intestazione non si attacca più in alto. Credo che questo sia causato dall'assenza di un'intestazione di sezione [0]. Dato che è zero, non riesce a trovare il punto critico. – jonypz
Ho rimesso la prima intestazione e ancora non funziona. Ora le intestazioni non si attaccano più. – jonypz
Prova a usare 'UICollectionViewLayoutAttributes * prevHeaderAttributes = [self layoutAttributesFor ...' invece di 'UICollectionViewLayoutAttributes * prevHeaderAttributes = [super ...'. La super chiamata non restituirà gli attributi corretti del prev. header – sgl0v