繁体   English   中英

在UICollectionView中边框和调整单元格的大小

[英]Bordering and resizing the cell in UICollectionView

如图所示

屏幕截图

我将基于UIViewController实现UICollectionView

这是我的代码:

class SettingViewController: BaseViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    @IBOutlet var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 3
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! SettingCollectionViewCell
        cell.backgroundColor = UIColor.greenColor()
        cell.lb.text = "Something"
        cell.img.image = UIImage(named: "setting")
        cell.layer.borderColor = UIColor.lightGrayColor().CGColor
        cell.layer.borderWidth = 1
        return cell;
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let screen = UIScreen.mainScreen().bounds
        return CGSize(width: CGFloat(screen.width/3 - 10), height: 120)
    }
}

结果是:

结果 :)))

我真的迷失了方向!
我实现了func sizeForItemAtIndexPath来调整单元格的大小,但是我得到的只是每个单元格之间的间距,它甚至没有相同的宽度,而且我也不知道如何在设计中获得边框。

请帮我!

这里的窍门是,我们需要创建自定义 UICollectionViewFlowLayout为:

CustomCollectionLayout.h

#import <UIKit/UIKit.h>

@protocol CustomCollectionLayoutDelegate      
<UICollectionViewDelegateFlowLayout>

@end

@interface CustomCollectionLayout : UICollectionViewFlowLayout
@end

CustomCollectionLayout.m

#import "CustomCollectionLayout.h"

@interface CustomCollectionLayout ()

@end

@implementation CustomCollectionLayout
{
    NSDictionary *_layoutInfo;
    CGFloat maxColumnHeight;
    __weak id<CustomCollectionLayoutDelegate> delegate;
}

- (void)prepareLayout{

    delegate = (id<CustomCollectionLayoutDelegate>) self.collectionView.delegate;
    //Calculate max values
    maxColumnHeight = [self maxColumnHeight];

    //Store calculated frames for cells in the dictionary
    NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];

    //Calculate Frame for a cell, per values from DataSource
    CGFloat originY = 0;
    NSInteger sectionCount = [self.collectionView numberOfSections];

    for (NSInteger section = 0; section < sectionCount; section++) {

        UIEdgeInsets itemInsets = UIEdgeInsetsZero;
        if ([delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
            itemInsets = [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
            originY += itemInsets.top;
        }

        CGFloat height = 0;
        NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
        CGFloat originX = itemInsets.left;

        for (NSInteger item = 0; item < itemCount; item++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];

            UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            CGSize itemSize = CGSizeZero;
            if ([delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)]) {
                itemSize = [delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
                float selectedOriginY = originY;
                itemAttributes.frame = CGRectMake(originX, selectedOriginY, itemSize.width, itemSize.height);
            }
            cellLayoutInfo[indexPath] = itemAttributes;

            CGFloat interItemSpacingX = 0;
            if ([delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
                interItemSpacingX = [delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:section];
            }

            originX += floorf(itemSize.width + interItemSpacingX);
            height = height > itemSize.height ? height : itemSize.height;
        }

        CGFloat interItemSpacingY = 0;
        if ([delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
            interItemSpacingY = [delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
        }

        originY += floor(height + interItemSpacingY);
    }

    _layoutInfo = cellLayoutInfo;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:_layoutInfo.count];

    [_layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
                                                     UICollectionViewLayoutAttributes *attributes,
                                                     BOOL *innerStop) {
        if (CGRectIntersectsRect(rect, attributes.frame)) {
            [allAttributes addObject:attributes];
        }
    }];

    return allAttributes;
}

- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
{
    return YES;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return _layoutInfo[indexPath];
}

- (CGSize)collectionViewContentSize
{
    CGFloat width = self.collectionView.frame.size.width;
    CGFloat height = maxColumnHeight;
    return CGSizeMake(width, height);
}

//Maximum Height of perticular Column in CollectionView
- (CGFloat)maxColumnHeight
{
    NSInteger sectionCount = [self.collectionView numberOfSections];
    CGFloat maxHeight = 0;
    for (NSInteger section = 0; section < sectionCount; section++) {
        NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
        CGFloat maxRowHeight = 0;
        for (NSInteger item = 0; item < itemCount; item++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
            if ([delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)]) {
                CGSize itemSize = [delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
                maxRowHeight = itemSize.height > maxRowHeight ? itemSize.height : maxRowHeight;
            }
        }
        CGFloat interSectionSpacingY = 0;
        if ([delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
            interSectionSpacingY = [delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
        }

        UIEdgeInsets itemInsets = UIEdgeInsetsZero;
        if ([delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
            itemInsets = [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
        }

        maxHeight += maxRowHeight;

        //Add interSectionSpacing and Insets for all sections except last.
        if (section != sectionCount-1) {
            maxHeight += interSectionSpacingY + itemInsets.top;
        }
    }

    return maxHeight;
}

@end

原谅我提供了Objective-C代码,但我们可以使用Bridging Header

然后使用以下自定义布局:

在此处输入图片说明 灰色是集合视图,而粉红色是单元格。

委托方法:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCellId", forIndexPath: indexPath)
    cell.backgroundColor = UIColor.greenColor()
    //cell.lb.text = "Something"
    //cell.img.image = UIImage(named: "setting")
    cell.layer.borderColor = UIColor.lightGrayColor().CGColor
    cell.layer.borderWidth = 1
    return cell;
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    let screen = UIScreen.mainScreen().bounds
    return CGSize(width: CGFloat(screen.width/3), height: 120)
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}

这是输出:
在此处输入图片说明

现在,我们可以使用任何自定义单元格并获得所需的外观。

希望这个能对您有所帮助!

对于自定义大小的单元格,请执行以下两种方法:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("hobbiesCell", forIndexPath: indexPath) as! HobbiesTagCell
        self.configureCell(cell, forIndexPath: indexPath)
        return cell
    } 

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        self.configureCell(self.sizingCell!, forIndexPath: indexPath)
        return self.sizingCell!.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
    }

对于单元之间相等的空间,请实现以下自定义流布局:

class CustomViewFlowLayout : UICollectionViewFlowLayout {

    let cellSpacing:CGFloat = 2

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        if let attributes = super.layoutAttributesForElementsInRect(rect) {
            for (index, attribute) in attributes.enumerate() {
                if index == 0 { continue }
                let prevLayoutAttributes = attributes[index - 1]
                let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                    attribute.frame.origin.x = origin + cellSpacing
                }
            }
            return attributes
        }
        return nil
    }
}

暂无
暂无

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

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