2

私は、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; 
} 

答えて

0

私は上記のコードがOKであるIが変化

方法は shouldInvalidateLayoutForBoundsChangeました。私が考えているクラッシュの原因は、JSQMessagesViewControllerサブクラスのcollectionView:collectionViewLayout:referenceSizeForHeaderInSection:関数をオーバーライドしたためです。私はその機能をコメントアウトし、代わりにkJSQMessagesLoadEarlierHeaderViewHeightの高さをJSQMessagesLoadEarlierHeaderViewに設定しました。はい、私は自分のカスタムヘッダービューを表示するためにLoadEarlierHeaderViewをハイジャックしました。

これで、ヘッダービューが上部に固定され、カスタムヘッダービューが表示され、クラッシュは発生しません。

関連する問題