Serious bug for UICollectionViewFlowLayout: minimu

2019-03-31 08:01发布

问题:

I am facing the following bug with UICollectionView in the horizontal scrolling mode (iOS 8, iOS 7, the only ones I have tested).

My question

I would like to have your views on this bug and on how I could elegantly solve it.

The setting up

UICollectionViewFlowLayout * layout ;
layout = [[UICollectionViewFlowLayout alloc] init] ;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal ;
layout.minimumInteritemSpacing = 5 ;
layout.minimumLineSpacing = 100 ;

The bug

It's difficult to explain but I will do my best. The bug happens when the cells in the UICollectionView does not have the same sizes.

  • when all the cells have the same size, it looks like this

  • but as soon as one of the cells have a different size than the others, it looks like this

So, it seems that it interchanges the minimumInteritemSpacing and minimumLineSpacing.

Link to a minimal non-working example

https://github.com/colasjojo/TEST_COLLECTION_VIEW_BUG

More code

#import "ViewController.h"
#import "MyCell.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *viewForCollectionView;
@property (nonatomic, assign, readwrite) NSInteger selectedIndex ;
@end

@implementation ViewController


//
//
/**************************************/
#pragma mark - Init
/**************************************/

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


- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil] ;
    if (self)
    {
        [self configure] ;
    }
    return self ;
}


- (void)configure
{
    _selectedIndex = -1 ;
}




//
//
/**************************************/
#pragma mark - Life cycle
/**************************************/


- (void)viewDidLoad {
    [super viewDidLoad];


    UICollectionViewFlowLayout * layout ;
    layout = [[UICollectionViewFlowLayout alloc] init] ;
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal ;
    layout.minimumInteritemSpacing = 5 ;
    layout.minimumLineSpacing = 100 ;



    UICollectionView * collectionView ;
    CGRect frame ;
    frame.size = self.viewForCollectionView.frame.size ;
    collectionView = [[UICollectionView alloc] initWithFrame:frame
                                        collectionViewLayout:layout] ;
    collectionView.dataSource = self ;
    collectionView.delegate = self ;
    collectionView.backgroundColor = [UIColor clearColor] ;

    [collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([MyCell class])
                                               bundle:nil]
     forCellWithReuseIdentifier:@"MyCell"] ;



    [self.viewForCollectionView addSubview:collectionView] ;

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}



//
//
/**************************************/
#pragma mark - Datasourcing
/**************************************/


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 100 ;
}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell * cell ;
    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell"
                                                     forIndexPath:indexPath] ;

    cell.label.text = [@([indexPath indexAtPosition:1]) stringValue] ; ;
    return cell ;
}


- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if ([indexPath indexAtPosition:1] == self.selectedIndex)
    {
        return CGSizeMake(200, 200) ;
    }
    else
    {
        return  CGSizeMake(110, 110) ;
    }
}


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSMutableArray * indexes = [NSMutableArray new] ;
    if (self.selectedIndex >= 0)
    {
        [indexes addObject:[NSIndexPath indexPathForItem:self.selectedIndex inSection:0]] ;
    }
    if (self.selectedIndex != [indexPath indexAtPosition:1])
    {
        [indexes addObject:indexPath] ;
        self.selectedIndex = [indexPath indexAtPosition:1] ;
    }
    else
    {
        self.selectedIndex = -1 ;
    }

    [collectionView reloadItemsAtIndexPaths:indexes] ;
}


@end