【问题标题】:How to display 3 cell per row UICollectionView如何每行显示 3 个单元格 UICollectionView
【发布时间】:2016-05-26 02:34:21
【问题描述】:

根据标题,我使用 UICollectionView 来显示图像。我需要每行显示 3 个单元格,就像 Instagram 是如何做到的。

因为有很多屏幕尺寸,我得到了 iPhone 屏幕的宽度,然后除以 3。但是,它并没有按照我的需要显示。

这是我在 viewDidLoad() 方法中的代码:

private let leftAndRightPaddings: CGFloat = 8.0
private let numberOfItemsPerRow: CGFloat = 3.0
private let heightAdjustment: CGFloat = 30.0    

let bounds = UIScreen.mainScreen().bounds
let width = (bounds.size.width - leftAndRightPaddings) / numberOfItemsPerRow
let layout = userDetailCollection.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSizeMake(width, width)

【问题讨论】:

    标签: ios cocoa-touch layout uicollectionview


    【解决方案1】:

    替换此行

    let width = (bounds.size.width - leftAndRightPaddings) / numberOfItemsPerRow
    

    let width = (bounds.size.width - leftAndRightPaddings*4) / numberOfItemsPerRow
    

    因为您没有考虑两个项目和右插图之间的间距 因此它不会在屏幕中调整间距。

    private let leftAndRightPaddings: CGFloat = 15.0
    private let numberOfItemsPerRow: CGFloat = 3.0
    
    let bounds = UIScreen.mainScreen().bounds
    let width = (bounds.size.width - leftAndRightPaddings*(numberOfItemsPerRow+1)) / numberOfItemsPerRow
    let layout = userDetailCollection.collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = CGSizeMake(width, width)   
    

    试试这个代码

    【讨论】:

    • 什么是 LeftandRightMarginPadding
    • 它是 8.0 的 CGFloat
    • 尝试增加它的价值
    • layout.itemSize = CGSizeMake(width, width) 尝试使用非常少的硬编码值设置宽度
    • 做这个 layout.itemSize = CGSizeMake(30, 30)
    【解决方案2】:

    覆盖UICollectionViewLayout 将使您在创建collectionViews 时更加灵活。这是YourOwnCollectionViewLayout : UICollectionViewLayout的sn-p:

    - (NSInteger)itemWidth {
        return (self.collectionView.bounds.size.width - (HORIZONTAL_PAD * (NUMBER_OF_ITEMS_PER_ROW+1))) / NUMBER_OF_ITEMS_PER_ROW; // pad from each side + pad in the middle
    }
    
    - (NSInteger)itemHeight {
        return self.itemWidth; // or something else
    }
    
    - (NSString *)keyForIndexPath:(NSIndexPath *)indexPath {
        NSString *retVal = [NSString stringWithFormat:@"%ld-%ld", (long)indexPath.section, (long)indexPath.row];
        return retVal;
    }
    
    - (CGRect)frameForItemAtIndexPath:(NSIndexPath *)indexPath {
        CGFloat itemWidth  = [self itemWidth];
        CGFloat itemHeight = [self itemHeight];
    
        CGFloat originX = HORIZONTAL_PAD + ((indexPath.row % NUMBER_OF_ITEMS_PER_ROW)*(HORIZONTAL_PAD + itemWidth));
        CGFloat originY = VERTICAL_PAD + (floorf(indexPath.row/NUMBER_OF_ITEMS_PER_ROW)*(VERTICAL_PAD + itemHeight));
    
        return CGRectMake(originX, originY, itemWidth, itemHeight);
    }
    
    - (void)prepareLayout {
        NSMutableDictionary *newLayoutInfo  = [NSMutableDictionary dictionary];
        NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];
    
        NSInteger sectionCount = [self.collectionView numberOfSections];
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
    
        for (NSInteger section = 0; section < sectionCount; section++) {
            NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
    
            for (NSInteger item = 0; item < itemCount; item++) {
                indexPath = [NSIndexPath indexPathForItem:item inSection:section];
    
                UICollectionViewLayoutAttributes *itemAttributes =
                [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
                itemAttributes.frame = [self frameForItemAtIndexPath:indexPath];
    
                NSString *key        = [self keyForIndexPath:indexPath];
                cellLayoutInfo[key]  = itemAttributes;
            }
        }
    
        newLayoutInfo[@"CellKind"] = cellLayoutInfo;
        self.layoutInfo            = newLayoutInfo;
    }
    
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
        NSString *key = [self keyForIndexPath:indexPath];
        UICollectionViewLayoutAttributes *retVal = self.layoutInfo[@"CellKind"][key];
        return retVal;
    }
    
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
        NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
    
        [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier,
                                                             NSDictionary *elementsInfo,
                                                             BOOL *stop) {
            [elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
                                                              UICollectionViewLayoutAttributes *attributes,
                                                              BOOL *innerStop) {
    
                if (CGRectIntersectsRect(rect, attributes.frame)) {
                    [allAttributes addObject:attributes];
                }
            }];
        }];
    
        return allAttributes;
    }
    
    - (CGSize)collectionViewContentSize {
        return CGSizeMake(self.collectionView.bounds.size.width, floorf([self.collectionView numberOfItemsInSection:0]/NUMBER_OF_ITEMS_PER_ROW) * (self.itemHeight + VERTICAL_PAD) + VERTICAL_PAD);
    }
    

    在你的 mainView 添加: [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:[[YourOwnCollectionViewLayout alloc] init]]; 你就完成了!

    【讨论】:

    • 可以提一下,自定义布局也可以在IB中设置。
    【解决方案3】:

    您没有考虑sectionInsetinterItemSpacing。它有一些默认值可以推动单元格(提供填充)。您可以将interItemSpacing 设置为 0,将sectionInset 设置为UIEdgeInsetsZero,或者在计算单元格宽度时必须考虑它们的值。

    覆盖这些协议方法以设置大小、插图和项目间间距

    optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
    
    optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
    
    optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
    
    optional public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat
    

    【讨论】:

    • 我已经添加了你提到的。 layout.sectionInset = UIEdgeInsetsZerolayout.minimumInteritemSpacing = 0 但还是一样。
    • 尝试在 UICollectionViewDelegateFlowLayout 方法中设置 sectionInset 和 interItemSpacing。我猜属性中的设置有时不起作用。还要在它的委托方法本身中设置大小
    • 嗯。对不起,我该怎么做?你是说myCollectionView.delegate = self吗?
    • 更新了答案。请检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多