UICollectionViewFlowLayout根据数据宽度

作者: LikeSmilence | 来源:发表于2016-03-01 09:22 被阅读3336次

由于功能原因想实现根据长度左对齐并且超过边距换行输出的效果(效果如图)


xiaoguo.png

以下是实现效果的代码

#import <UIKit/UIKit.h>

@protocol SearchOfFlowLayoutDelegate <NSObject>

// 获取item高度
- (CGFloat)widthForItemIndexPath:(NSIndexPath *)indexPath AndCollectioinView:(UICollectionView *)collectionView;

@end

@interface SearchOfFlowLayout : UICollectionViewFlowLayout

@property (nonatomic, assign) id<SearchOfFlowLayoutDelegate>delegate;

// item 间距
@property (nonatomic,assign)CGFloat insertItemSpacing;

@end
#import "SearchOfFlowLayout.h"

#define WIDTH [UIScreen mainScreen].bounds.size.width

@interface SearchOfFlowLayout ()
//临时保存item的总宽度
@property (nonatomic, assign) CGFloat columnWidth;
//记录一共有多少行
@property (nonatomic, assign) NSInteger columnNumber;
//保存每一个item x y w h
@property (nonatomic, retain) NSMutableArray *arrForItemAtrributes;
//保存item总数
@property (nonatomic,assign) NSUInteger numberOfItems;
// 保存每个item的X值
@property (nonatomic, assign) CGFloat xForItemOrigin;
// 保存每个item的Y值
@property (nonatomic, assign) CGFloat yForItemOrigin;

@end


@implementation SearchOfFlowLayout

// 准备布局
- (void)prepareLayout {
    
    [super prepareLayout];
    
    self.columnWidth = self.insertItemSpacing;
    self.columnNumber = 0;
    self.arrForItemAtrributes = [NSMutableArray array];
    self.xForItemOrigin = self.insertItemSpacing;
    self.yForItemOrigin = self.insertItemSpacing;
    
    //获取item的个数
    self.numberOfItems = [self.collectionView numberOfItemsInSection:0];
    /** 为每个item确定LayoutAttribute属性,同时将这些属性放入布局数组中 */
    for(int i = 0;i < self.numberOfItems;i++)
    {
        /** 确定每个Item的indexPath属性 */
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        /** 确定每个item的origin的x,y值 */
        /** 确定每个Item的frame属性,同时确定了每个Item的LayoutAttribute,放入到了布局属性数组中 */
        [self setFrame:indexPath];
    }

}
// 计算contentView的大小
- (CGSize)collectionViewContentSize
{
    // 获取collectionView的Size
    CGSize contentSize = self.collectionView.frame.size;
    // 最大高度+bottom
    contentSize.height = self.insertItemSpacing + (self.itemSize.height + self.insertItemSpacing) * (self.columnNumber + 1);
    //设置collectionView的大小自适应
    self.collectionView.frame = CGRectMake(self.collectionView.frame.origin.x, self.collectionView.frame.origin.y, contentSize.width, contentSize.height);
   return contentSize;
}

// 返回每一个item的attribute
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 返回每一个item的Attribute
    return self.arrForItemAtrributes;
}

// 设置属性和frame
- (void)setFrame:(NSIndexPath *)indexPath
{
    // 设置Item LayoutAttribute 属性
    UICollectionViewLayoutAttributes *layoutArr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    // 获取item的高
    CGFloat itemWidth = 0;
    if (_delegate && [_delegate respondsToSelector:@selector(widthForItemIndexPath:AndCollectioinView:)]) {
        // 使用代理方法获取item的高
        itemWidth = [_delegate widthForItemIndexPath:indexPath AndCollectioinView:self.collectionView];
    }
    //之前item的宽总和 + 当前item的宽 + 间距 < 屏幕总款
    if (self.columnWidth + itemWidth + self.insertItemSpacing < WIDTH) {
        //设置x
        self.xForItemOrigin = self.columnWidth;
        self.columnWidth += itemWidth + self.insertItemSpacing;
    }else {
        self.xForItemOrigin = self.insertItemSpacing;
        //如果宽度超过屏幕从新计算宽度
        self.columnWidth = itemWidth + self.insertItemSpacing * 2;
        self.columnNumber++;
    }
    // 计算是第几行 乘以高度
    self.yForItemOrigin = self.insertItemSpacing + (self.itemSize.height + self.insertItemSpacing) * self.columnNumber;
    
    // 设置frame
    layoutArr.frame = CGRectMake(self.xForItemOrigin, self.yForItemOrigin, itemWidth, self.itemSize.height);
    // 放入数组
    [self.arrForItemAtrributes addObject:layoutArr];
}
@end

以下是实现代理的方法 根据文本的长度判断文本的宽度, 根据tag控制是哪个collection

- (CGFloat)widthForItemIndexPath:(NSIndexPath *)indexPath AndCollectioinView:(UICollectionView *)collectionView{
    if (collectionView.tag == 1001) {
        NSString *content = self.hotTagArr[indexPath.item];
        CGRect itemFrame = [content boundingRectWithSize:CGSizeMake(0, 20) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:17]} context:nil];
        
        CGFloat width = itemFrame.size.width + 10;
        return width;
    }
    return 10;
}

相关文章

  • UICollectionViewFlowLayout根据数据宽度

    由于功能原因想实现根据长度左对齐并且超过边距换行输出的效果(效果如图) 以下是实现效果的代码 以下是实现代理的方法...

  • UICollectionViewFlowLayout计算item

    使用UICollectionViewFlowLayout时, cell的宽度计算误差导致collectionVie...

  • iOS Swift 自适应宽度历史记录标签

    自适应宽度历史记录标签 实现: 自定义 UICollectionViewFlowLayout

  • iOS-Swift-UICollectionViewCell居左

    如下图要实现内容居左对齐,先获取每个cell的宽度,然后自定义UICollectionViewFlowLayout...

  • 2018-03-07

    自定义UICollectionViewFlowLayout UICollectionViewFlowLayout是...

  • 八、分列 快速提取有效信息

    1.基本用法 分隔符号 数据—分列——分隔符号—根据分隔符号选择—目标区域(旁边区域) 固定宽度 数据—分列——固...

  • 图片根据屏幕大小切换自适应

    根据不同屏幕宽度取不同大小的图片 拿到屏幕的宽度 与一个值比较,判断是不大屏还是小屏 拿到对象,给对象挷定数据 ...

  • 瀑布流布局

    定义 一堆 等宽 不等高 的数据块组成的页面。 排列规则 根据图片的宽度和页面的宽度算比例算出列数。 第一行就是按...

  • R 数据可视化 —— circlize 高级布局

    1. 放大扇形 默认情况下,扇形的宽度(即角度大小)是根据数据范围自动确定的,一般也不会去修改其宽度。如果修改扇形...

  • 进制和内存

    进制和内存 数据宽度 因为计算机受硬件制约,数据都是有长度限制的(数据宽度),超过最多宽度的数据会被丢弃 计算机中...

网友评论

  • 王阿冲冲:你好 不支持分组的吗 有组头的那种
  • Civel_Xu:中间对齐的有吗
    LikeSmilence::joy: :joy: 没有
  • GOOGxu:当一个cell的宽超过屏幕时 self.columnNumber++会导致collectionView的尺寸变大 不知道怎么弄 :persevere:
    浪漫小牛:当cell重用的时候会出问题的
    GOOGxu:@LikeSmilence 好吧
    LikeSmilence:@霍GOOG旭 写太久了 自己也不知道怎么写的了。

本文标题:UICollectionViewFlowLayout根据数据宽度

本文链接:https://www.haomeiwen.com/subject/rkggkttx.html