简体   繁体   English

Swift:UICollection视图布局问题

[英]Swift: Issues with UICollection View layout

I am trying to layout a UICollectionView like the mock-up I have drawn in the photo(also showing the index of each item): 我正在尝试布局UICollectionView,就像我在照片中绘制的模型一样(还显示每个项目的索引):

在此处输入图片说明

The code I currently have to try and achieve this is: 我目前必须尝试实现的代码是:

In ViewDidLoad: 在ViewDidLoad中:

collectionView.dataSource = self
    collectionView.delegate = self

    flowLayout.scrollDirection = .horizontal
    flowLayout.minimumLineSpacing = 5
    flowLayout.minimumInteritemSpacing = 5
    flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 5)

Then later on the the file: 然后在文件上:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let totalWidth = collectionView.bounds.size.width
    let totalHeight = collectionView.bounds.size.height
    let heightOfView = totalHeight / 3
    let numberOfCellsPerRow = 1
    let dimensions = CGFloat(Int(totalWidth) / numberOfCellsPerRow)
    if (indexPath.item == 4) {
        return CGSize(width: collectionView.bounds.size.width, height: heightOfView)
    } else {
        return CGSize(width: dimensions / 2, height: heightOfView)
    }
}

This code isn't having the desired effect, and is producing a UICollectionView that looks like this: 这段代码没有达到预期的效果,并且正在产生一个如下的UICollectionView:

在此处输入图片说明

As you can see, the cells are not even in the UICollectionView , with the right-hand side cells overflowing into scroll space. 如您所见,单元格甚至UICollectionView ,右侧单元格溢出到滚动空间中。 The section gaps between the items are wrong and the 5th, the larger cell is on the right-hand side of the screen out of view unless scrolled to. 项之间的节距是错误的,第5个,除非滚动到较大的单元格,否则它们将位于屏幕的右侧。

You cannot create such layout with standard UICollectionViewFlowLayout class. 您无法使用标准UICollectionViewFlowLayout类创建此类布局。 First of all watch WWDC videos related to UICollectionView and it's layout: https://developer.apple.com/videos/play/wwdc2012/219/ . 首先,观看与UICollectionView相关的WWDC视频及其布局: https : //developer.apple.com/videos/play/wwdc2012/219/ Then you can check Swift tutorials with sample code to get started: http://swiftiostutorials.com/tutorial-creating-custom-layouts-uicollectionview/ 然后,您可以查看带有示例代码的Swift教程以开始使用: http : //swiftiostutorials.com/tutorial-creating-custom-layouts-uicollectionview/

Simplest working, but not best structured will be such code in custom UICollectionViewLayout . 自定义UICollectionViewLayout代码将是最简单的工作,但结构最好的UICollectionViewLayout Use this as a starting point: 以此为起点:

@interface UICollectionViewCustomLayout ()

@property (nonatomic) NSArray<UICollectionViewLayoutAttributes *> *attributes;
@property (nonatomic) CGSize size;

@end

@implementation UICollectionViewCustomLayout

- (void)prepareLayout
{
    [super prepareLayout];

    NSMutableArray<UICollectionViewLayoutAttributes *> *attributes = [NSMutableArray new];

    id<UICollectionViewDelegate> delegate = (id<UICollectionViewDelegate>)self.collectionView.delegate;
    id<UICollectionViewDataSource> dataSource = (id<UICollectionViewDataSource>)self.collectionView.dataSource;

    NSInteger count = [dataSource collectionView:self.collectionView numberOfItemsInSection:0];
    CGFloat collectionViewWidth = CGRectGetWidth(self.collectionView.frame);
    CGFloat collectionViewHeight = CGRectGetHeight(self.collectionView.frame);
    CGFloat rowHeight = floor(collectionViewHeight / 3);
    NSUInteger numberOfPages = count / 5;
    if (count % 5) {
        numberOfPages++;
    }

    for (NSInteger item = 0; item < count; item++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0];
        UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

        NSInteger index = item % 5;
        NSInteger page = item / 5;
        CGFloat width = index == 4 ? collectionViewWidth : collectionViewWidth / 2;
        CGSize size = CGSizeMake(width, rowHeight);
        CGFloat x = page * collectionViewWidth + (index % 2 == 0 ? 0 : collectionViewWidth / 2);
        CGFloat y = (index / 2) * rowHeight;
        CGPoint origin = CGPointMake(x, y);
        CGRect frame = CGRectZero;
        frame.size = size;
        frame.origin = origin;
        attribute.frame = frame;
        [attributes addObject:attribute];
    }
    self.attributes = attributes;

    self.size = CGSizeMake(numberOfPages * collectionViewWidth, collectionViewHeight);
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray<UICollectionViewLayoutAttributes *> *result = [NSMutableArray new];
    for (UICollectionViewLayoutAttributes *attribute in self.attributes) {
        if (CGRectIntersectsRect(attribute.frame, rect)) {
            [result addObject:attribute];
        }
    }
    return result;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"indexPath.section == %@ AND indexPath.item == %@", @(indexPath.section), @(indexPath.item)];
    UICollectionViewLayoutAttributes *attributes = [self.attributes filteredArrayUsingPredicate:predicate].firstObject;
    return attributes;
}

- (CGSize)collectionViewContentSize
{
    return self.size;
}

@end

And controller: 和控制器:

// Views
#import "UICollectionViewCustomLayout.h"

@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>

@property (nonatomic) UICollectionView *collectionView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[UICollectionViewCustomLayout new]];
    self.collectionView.backgroundColor = [UIColor whiteColor];
    self.collectionView.frame = self.view.bounds;
    self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class])];
    [self.view addSubview:self.collectionView];
}

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

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
    NSArray *colors = @[[UIColor redColor], [UIColor blueColor], [UIColor grayColor], [UIColor greenColor], [UIColor purpleColor], [UIColor cyanColor]];

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath];
    cell.contentView.backgroundColor = colors[arc4random() % colors.count];
    cell.contentView.alpha = (arc4random() % 500 + 500) / 1000.0;
    return cell;
}

@end

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM