私は、collectionView:viewForSupplementaryElementOfKind:atIndexPathをオーバーライドしました。私のJSQMessagesViewControllerサブクラスのヘッダービューをswiftで表示します。これは本当にうまくいきますが、ヘッダービューはチャットと一緒にスクロールし、上に固定したいと思います。補足ビューが上に固定されたJSQMessagesViewController
AppleはiOS 9でsectionHeadersPinToVisibleBoundsプロパティを導入しました。これは固定ヘッダービューを持つ必要がありますが、何らかの理由でこれがJSQMessagesViewControllerサブクラスで機能しません。私は
(この記事How to make Supplementary View float in UICollectionView as Section Headers do in UITableView plain styleから)私が試した別の解決策は、JSQMessagesCollectionViewFlowLayoutをサブクラス化することだったのviewDidLoadに 真 self.collectionView.collectionViewLayout.sectionHeadersPinToVisibleBoundsを=()を添加しており、これはほとんど働いていました。スワイプすると、ヘッダービューは上に固定され、チャットメッセージはヘッダービューの下にプッシュされます。しかし、すぐに、私は下にスワイプしてみて、私は私のコンソールで次のエラーが表示されるアプリがクラッシュしたとき:
*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.60.12/UICollectionViewData.m:408
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'layout attributes for supplementary item at index path (<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}) changed from <JSQMessagesCollectionViewLayoutAttributes: 0x13f65a730> index path: (<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 0; 414 100); zIndex = 10; to <JSQMessagesCollectionViewLayoutAttributes: 0x13f679920> index path: (<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 10; 414 100); zIndex = 1024; without invalidating the layout'
は、誰もがJSQMessagesViewControllerのために同じ方法で、ヘッダビューを固定し、成功したことがありますか?私はYES返さ 、
とlayoutAttributesForElementsInRect:私は変更された:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *attributesInRect = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
// if (self.springinessEnabled) {
// NSMutableArray *attributesInRectCopy = [attributesInRect mutableCopy];
// NSArray *dynamicAttributes = [self.dynamicAnimator itemsInRect:rect];
//
// // avoid duplicate attributes
// // use dynamic animator attribute item instead of regular item, if it exists
// for (UICollectionViewLayoutAttributes *eachItem in attributesInRect) {
//
// for (UICollectionViewLayoutAttributes *eachDynamicItem in dynamicAttributes) {
// if ([eachItem.indexPath isEqual:eachDynamicItem.indexPath]
// && eachItem.representedElementCategory == eachDynamicItem.representedElementCategory) {
//
// [attributesInRectCopy removeObject:eachItem];
// [attributesInRectCopy addObject:eachDynamicItem];
// continue;
// }
// }
// }
//
// attributesInRect = attributesInRectCopy;
// }
UICollectionView * const cv = self.collectionView;
CGPoint const contentOffset = cv.contentOffset;
NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
for (UICollectionViewLayoutAttributes *layoutAttributes in attributesInRect) {
if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
[missingSections removeIndex:layoutAttributes.indexPath.section];
}
}
[attributesInRect enumerateObjectsUsingBlock:^(JSQMessagesCollectionViewLayoutAttributes *attributesItem, NSUInteger idx, BOOL *stop) {
if (attributesItem.representedElementCategory == UICollectionElementCategoryCell) {
[self jsq_configureMessageCellLayoutAttributes:attributesItem];
[missingSections addIndex:attributesItem.indexPath.section];
}
else {
attributesItem.zIndex = -1;
}
}];
[missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
[attributesInRect addObject:layoutAttributes];
}];
for (UICollectionViewLayoutAttributes *layoutAttributes in attributesInRect) {
if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
NSInteger section = layoutAttributes.indexPath.section;
NSInteger numberOfItemsInSection = [cv numberOfItemsInSection:section];
NSIndexPath *firstCellIndexPath = [NSIndexPath indexPathForItem:0 inSection:section];
NSIndexPath *lastCellIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section];
NSIndexPath *firstObjectIndexPath = [NSIndexPath indexPathForItem:0 inSection:section];
NSIndexPath *lastObjectIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section];
UICollectionViewLayoutAttributes *firstObjectAttrs;
UICollectionViewLayoutAttributes *lastObjectAttrs;
if (numberOfItemsInSection > 0) {
firstObjectAttrs = [self layoutAttributesForItemAtIndexPath:firstObjectIndexPath];
lastObjectAttrs = [self layoutAttributesForItemAtIndexPath:lastObjectIndexPath];
} else {
firstObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:firstObjectIndexPath];
lastObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter atIndexPath:lastObjectIndexPath];
}
CGFloat headerHeight = CGRectGetHeight(layoutAttributes.frame);
CGPoint origin = layoutAttributes.frame.origin;
origin.y = MIN(MAX(contentOffset.y + cv.contentInset.top, (CGRectGetMinY(firstObjectAttrs.frame) - headerHeight)), (CGRectGetMaxY(lastObjectAttrs.frame) - headerHeight));
layoutAttributes.zIndex = 1024;
layoutAttributes.frame = (CGRect) {
.origin = origin, .size = layoutAttributes.frame.size
};
}
}
return attributesInRect;
}