菜鸟教程小白 发表于 2022-12-11 16:36:22

ios - 顶部固定有 SupplementaryView 的 JSQMessagesViewController


                                            <p><p>
我已经覆盖了 collectionView:viewForSupplementaryElementOfKind:atIndexPath: 以快速显示我的 JSQMessagesViewController 子类的标题 View 。这确实很好用,但标题 View 会随着聊天滚动,我希望将其固定在顶部。</p>

<p>Apple 在 iOS 9 中引入了 sectionHeadersPinToVisibleBounds 属性,这应该有固定的标题 View ,但由于某种原因,这在 JSQMessagesViewController 子类中不起作用。我已经添加了
    self.collectionView.collectionViewLayout.sectionHeadersPinToVisibleBounds = true
查看DidLoad()</p>

<p>我尝试的另一个解决方案(来自这篇文章 <a href="https://stackoverflow.com/q/13511733/6394244" rel="noreferrer noopener nofollow">How to make Supplementary View float in UICollectionView as Section Headers do in UITableView plain style</a> )是继承 JSQMessagesCollectionViewFlowLayout,这几乎奏效了。向上滑动时,标题 View 固定在顶部,聊天消息推送到标题 View 下方。但是,当我尝试向下滑动时,当应用崩溃时,我的控制台中会收到以下错误:</p>

<pre class="lang-swift prettyprint-override"><code>*** Assertion failure in -, /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.60.12/UICollectionViewData.m:408
*** Terminating app due to uncaught exception &#39;NSInternalInconsistencyException&#39;, reason: &#39;layout attributes for supplementary item at index path (&lt;NSIndexPath: 0xc000000000000016&gt; {length = 2, path = 0 - 0}) changed from &lt;JSQMessagesCollectionViewLayoutAttributes: 0x13f65a730&gt; index path: (&lt;NSIndexPath: 0xc000000000000016&gt; {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 0; 414 100); zIndex = 10;to &lt;JSQMessagesCollectionViewLayoutAttributes: 0x13f679920&gt; index path: (&lt;NSIndexPath: 0xc000000000000016&gt; {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 10; 414 100); zIndex = 1024;without invalidating the layout&#39;
</code></pre>

<p>有没有人以同样的方式为 JSQMessagesViewController 成功修复了标题 View ?</p>

<p>我改变的方法是
    shouldInvalidateLayoutForBoundsChange:
我返回的是,</p>

<p>和 layoutAttributesForElementsInRect: 我改为:</p>

<pre class="lang-swift prettyprint-override"><code>- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attributesInRect = [ mutableCopy];

//    if (self.springinessEnabled) {
//      NSMutableArray *attributesInRectCopy = ;
//      NSArray *dynamicAttributes = ;
//      
//      //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 (
//                  &amp;&amp; eachItem.representedElementCategory == eachDynamicItem.representedElementCategory) {
//                  
//                  ;
//                  ;
//                  continue;
//                }
//            }
//      }
//      
//      attributesInRect = attributesInRectCopy;
//    }
    UICollectionView * const cv = self.collectionView;
    CGPoint const contentOffset = cv.contentOffset;
    NSMutableIndexSet *missingSections = ;


    for (UICollectionViewLayoutAttributes *layoutAttributes in attributesInRect) {
      if () {
            ;
      }
    }

    [attributesInRect enumerateObjectsUsingBlock:^(JSQMessagesCollectionViewLayoutAttributes *attributesItem, NSUInteger idx, BOOL *stop) {
      if (attributesItem.representedElementCategory == UICollectionElementCategoryCell) {
            ;
            ;
      }
      else {
            attributesItem.zIndex = -1;
      }
    }];

    [missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
      NSIndexPath *indexPath = ;
      UICollectionViewLayoutAttributes *layoutAttributes = ;
      ;
    }];

    for (UICollectionViewLayoutAttributes *layoutAttributes in attributesInRect){
      if () {
            NSInteger section = layoutAttributes.indexPath.section;
            NSInteger numberOfItemsInSection = ;
            NSIndexPath *firstCellIndexPath = ;
            NSIndexPath *lastCellIndexPath = ;
            NSIndexPath *firstObjectIndexPath = ;
            NSIndexPath *lastObjectIndexPath = ;
            UICollectionViewLayoutAttributes *firstObjectAttrs;
            UICollectionViewLayoutAttributes *lastObjectAttrs;
            if (numberOfItemsInSection &gt; 0) {
                firstObjectAttrs = ;
                lastObjectAttrs = ;

            } else {
                firstObjectAttrs = ;
                lastObjectAttrs = ;
            }
            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;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我上面提供的代码是可以的。我认为导致崩溃的原因是我在 <code>JSQMessagesViewController</code> 子类中覆盖了 <code>collectionView:collectionViewLayout:referenceSizeForHeaderInSection:</code> 函数。我注释掉了该函数,而是在 <code>JSQMessagesLoadEarlierHeaderView</code> 中的 <code>kJSQMessagesLoadEarlierHeaderViewHeight</code> 常量中设置了高度。是的,我劫持了 LoadEarlierHeaderView 以显示我自己的自定义标题 View 。</p>

<p>现在,标题 View 固定在顶部,显示了我的自定义标题 View ,并且没有任何崩溃。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 顶部固定有 SupplementaryView 的 JSQMessagesViewController,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/37499713/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/37499713/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 顶部固定有 SupplementaryView 的 JSQMessagesViewController