首页 > 解决方案 > 带有 contentOffset 的 UICollectionView 粘性列故障

问题描述

问题

我创建了一个UICollectionViewFlowLayout使用粘性顶行和粘性左列的。通过这种布局,我还向 collectionView 添加了捏合手势以启用缩放。

当 collectionView 没有一直滚动到右侧或底部时,缩放效果很好;当这是真的contentOffset.x并且contentOffset.y行为怪异时。

谁能发现问题?我一直在尝试调试这个问题一段时间。这是一个gif表示:

在此处输入图像描述

代码

网格

- (void)actionPinchGesture:(UIPinchGestureRecognizer *)gesture {
   
   MyCustomLayout *layout = (MyCustomLayout *)self.gridView.collectionViewLayout;
   
   if (gesture.state == UIGestureRecognizerStateBegan) {
      [layout setPreviousPinchValue:gesture.scale];
   }
 
   if (gesture.state == UIGestureRecognizerStateChanged) {
      [layout setPinchValue:gesture.scale];
      [layout updatePinchValues];
   }
   
}

MyCustomLayout.h

@property (nonatomic, assign) previousPinchValue;
@property (nonatomic, assign) pinchValue;
- (void)updateGridScale;

我的自定义布局.m

@interface MyCustomLayout() {

    CGFloat zoomLevel;              //  stored zoom level.
    CGFloat cachedSectionWidth;     //  stored original section width.
    CGFloat cachedColumnWidth;      //  stored original column width.
    CGFloat cachedRowHeight;        //  stored row height.

    // these values above are cached when the grid is setup for the first time

}
@end

@implementation MyCustomLayout

- (void)updateGridScale {
   
    float scaleDeltaFactor     =   self.pinchValue / self.previousPinchValue;
    float currentZoom          =   self->zoomLevel;
    float newZoom              =   currentZoom * scaleDeltaFactor;
    float kMaxZoom             =   2.0;
    float kMinZoom             =   0.47;

    newZoom                    =   MAX(kMinZoom, MIN(newZoom, kMaxZoom));

    self->zoomLevel            =   newZoom;
    self.previousPinchValue    =   self.pinchValue;

    CGFloat sectionWidth       =   self->cachedSectionWidth;
    CGFloat columnWidth        =   self->cachedColumnWidth;
    CGFloat rowHeight          =   self->cachedRowHeight;

    sectionWidth = sectionWidth * newZoom;
    columnWidth = columnWidth * newZoom;
    rowHeight = rowHeight * newZoom;
    
    if (newZoom == 1 || newZoom == 0) {
        sectionWidth = self->cachedSectionWidth;
        columnWidth = self->cachedColumnWidth;
    }
    
    self.topColumnWidth = columnWidth;
    self.sectionHeight = rowHeight;
    [self invalidateLayoutCache];
    [self.collectionView reloadData];

}

- (void)prepareLayout {
    
    [super prepareLayout];
    [self prepareAttributesForRows:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];
    [self.allAttributes addObjectsFromArray:self.sectionAttributes];
    
}

- (void)prepareAttributesForRows:(NSIndexSet *)sectionIndexes {
    
    NSIndexPath *sectionIndexPath           =   [NSIndexPath indexPathForItem:0 inSection:section];
    CGFloat sectionMinY                     =   self.hourHeaderHeight + self.contentMargin.top;
    CGFloat sectionMinX                     =   (self.collectionView.contentOffset.x - 0.5) - self.collectionView.contentInset.left;
    CGFloat sectionY                        =   sectionMinY + ((self.sectionHeight + self.sectionGap) * section);
    CGFloat height                          =   self.sectionHeight + 1;
    
    UICollectionViewLayoutAttributes *atts  =   [self layoutAttributesForSupplementaryViewAtIndexPath:sectionIndexPath ofKind:INSEPGLayoutElementKindSectionHeader withItemCache:self.sectionHeaderAttributes];
    atts.frame                              =   CGRectMake(sectionMinX, sectionY, self.sectionHeaderWidth + 1.5, height);
    atts.zIndex                             =   [self zIndexForElementKind:INSEPGLayoutElementKindSectionHeader floating:YES];
    
    NSString *indexPathString               =   [NSString stringWithFormat:@"%li", sectionIndexPath.section];
    NSNumber *y_value                       =   [NSNumber numberWithFloat:round(sectionY)];

    if (![[self.cachedSectionInfo allKeys] containsObject:indexPathString]) {
        [self.cachedSectionInfo setObject:y_value forKey:indexPathString];
    }
    
}

@end

标签: iosobjective-cxcodeuicollectionviewuicollectionviewlayout

解决方案


推荐阅读