9

我有一個水平的UICollectionView。我想讓這些單元格彼此重疊60像素,以便第二個單元格重疊60個像素,第三個重疊第二個單元格,等等。UICollectionView Cell Overlap

我試過子分類UICollectionViewFlowLayout。但是我無法將UICollectionviewCell放在另一個上面。

回答

8

本教程開始:https://web-beta.archive.org/web/20151116053251/http://blog.tobiaswiedenmann.com/post/35135290759/stacklayout

我修改stacklayout專門爲水平UICollectionView

UICollectionViewStackLayout.h

#import <UIKit/UIKit.h> 

@interface UICollectionViewStackLayout : UICollectionViewFlowLayout 

#define STACK_OVERLAP 60 //this corresponds to 60 points which is probably what you want, not pixels 
#define ITEM_SIZE CGSizeMake(190,210) 

@end 

UICollectionViewStackLayout.m

#import "UICollectionViewStackLayout.h" 

@implementation UICollectionViewStackLayout 

-(id)init{ 

    self = [super init]; 

    if (self) { 
     [self commonInit]; 
    } 

    return self; 
} 

-(id)initWithCoder:(NSCoder *)aDecoder 
{ 
    if (self = [super init]) { 
     [self commonInit]; 
    } 

    return self; 
} 

-(void)commonInit 
{ 
    self.itemSize = ITEM_SIZE; 

    //set minimum layout requirements 
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 
    self.minimumInteritemSpacing = 0; 
} 

-(CGSize)collectionViewContentSize 
{ 
    NSInteger xSize = [self.collectionView numberOfItemsInSection:0] 
    * self.itemSize.width; 
    NSInteger ySize = [self.collectionView numberOfSections] 
    * (self.itemSize.height); 

    CGSize contentSize = CGSizeMake(xSize, ySize); 

    if (self.collectionView.bounds.size.width > contentSize.width) 
     contentSize.width = self.collectionView.bounds.size.width; 

    if (self.collectionView.bounds.size.height > contentSize.height) 
     contentSize.height = self.collectionView.bounds.size.height; 

    return contentSize; 
} 

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect 
{ 
    NSArray* attributesArray = [super layoutAttributesForElementsInRect:rect]; 
    int numberOfItems = [self.collectionView numberOfItemsInSection:0]; 

    for (UICollectionViewLayoutAttributes *attributes in attributesArray) { 
     CGFloat xPosition = attributes.center.x; 
     CGFloat yPosition = attributes.center.y; 

     if (attributes.indexPath.row == 0) { 
      attributes.zIndex = INT_MAX; // Put the first cell on top of the stack 
     } else { 
      xPosition -= STACK_OVERLAP * attributes.indexPath.row; 
      attributes.zIndex = numberOfItems - attributes.indexPath.row; //Other cells below the first one 
     } 

     attributes.center = CGPointMake(xPosition, yPosition); 
    } 

    return attributesArray; 
} 

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path { 
    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]; 
    return attributes; 
} 

@end 
1

我用mdewitt的一個swer,將其轉換爲swift 3,我的工作很棒! 對於任何感興趣的人:

class CollectionViewOverlappingLayout: UICollectionViewFlowLayout { 

var overlap: CGFloat = 30 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self.scrollDirection = .horizontal 
    self.minimumInteritemSpacing = 0 
} 

override var collectionViewContentSize: CGSize{ 
    let xSize = CGFloat(self.collectionView!.numberOfItems(inSection: 0)) * self.itemSize.width 
    let ySize = CGFloat(self.collectionView!.numberOfSections) * self.itemSize.height 

    var contentSize = CGSize(width: xSize, height: ySize) 

    if self.collectionView!.bounds.size.width > contentSize.width { 
     contentSize.width = self.collectionView!.bounds.size.width 
    } 

    if self.collectionView!.bounds.size.height > contentSize.height { 
     contentSize.height = self.collectionView!.bounds.size.height 
    } 

    return contentSize 
} 

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 

    let attributesArray = super.layoutAttributesForElements(in: rect) 
    let numberOfItems = self.collectionView!.numberOfItems(inSection: 0) 

    for attributes in attributesArray! { 
     var xPosition = attributes.center.x 
     let yPosition = attributes.center.y 

     if attributes.indexPath.row == 0 { 
      attributes.zIndex = Int(INT_MAX) // Put the first cell on top of the stack 
     } else { 
      xPosition -= self.overlap * CGFloat(attributes.indexPath.row) 
      attributes.zIndex = numberOfItems - attributes.indexPath.row //Other cells below the first one 
     } 

     attributes.center = CGPoint(x: xPosition, y: yPosition) 
    } 

    return attributesArray 
} 

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { 
    return UICollectionViewLayoutAttributes(forCellWith: indexPath) 
} 
}