ios uicollectionview实现横向滚动

现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo

实现上我选择了使用UICollectionView ;用UICollectionViewFlowLayout来定制样式;下面看看具体实现

效果

实现上我选择了使用UICollectionView ;用UICollectionViewFlowLayout来定制样式;下面看看具体实现

具体实现

1、ViViewController.m 代码实现

#import "ViewController.h"

#import "CollModel.h"

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

#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height

#define SCREEN_RATE ([UIScreen mainScreen].bounds.size.width/375.0)

#import "imageCell.h"

#import "LHHorizontalPageFlowlayout.h"

static NSString * const imageC = @"imageCell";

static NSString * const moreImageC = @"imageCell";

static const NSInteger kItemCountPerRow = 5; //每行显示5个

static const NSInteger kRowCount = 3; //每页显示行数

static float imageHeight = 80;//cell 高度

@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>

@property (nonatomic, span) UICollectionView * collectionView;

@property (nonatomic, span) NSMutableArray * modelArray;

@property (nonatomic, span) UICollectionView * moreCollectionView;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

NSArray *appArray = [[self getDict] objectForKey:@"dictInfo"];

for (int i = 0; i < appArray.count; i++) {

NSDictionary * appDic = appArray[i];

CollModel * model = [[CollModel alloc]init];

model.title = [appDic objectForKey:@"title"];

model.url = [appDic objectForKey:@"url"];

[self.modelArray addObject:model];

}

[self createCollectionView];

[self createRightCollectionView];

}

- (NSDictionary *)getDict {

NSString * string = @"{\"dictInfo\":[{\"title\":\"你好啊\",\"url\":\"1.jpeg\"},{\"title\":\"你好啊\",\"url\":\"2.jpeg\"},{\"title\":\"你好啊\",\"url\":\"3.jpeg\"},{\"title\":\"你好啊\",\"url\":\"4.jpeg\"},{\"title\":\"你好啊\",\"url\":\"5.jpeg\"},{\"title\":\"你好啊\",\"url\":\"6.jpeg\"},{\"title\":\"是很好\",\"url\":\"7.jpeg\"},{\"title\":\"你好啊\",\"url\":\"1.jpeg\"},{\"title\":\"你好啊\",\"url\":\"2.jpeg\"},{\"title\":\"你好啊\",\"url\":\"3.jpeg\"},{\"title\":\"你好啊\",\"url\":\"4.jpeg\"},{\"title\":\"你好啊\",\"url\":\"5.jpeg\"},{\"title\":\"你好啊\",\"url\":\"6.jpeg\"},{\"title\":\"是很好\",\"url\":\"7.jpeg\"},{\"title\":\"你好啊\",\"url\":\"1.jpeg\"},{\"title\":\"你好啊\",\"url\":\"2.jpeg\"},{\"title\":\"你好啊\",\"url\":\"3.jpeg\"},{\"title\":\"你好啊\",\"url\":\"4.jpeg\"},{\"title\":\"你好啊\",\"url\":\"5.jpeg\"},{\"title\":\"你好啊\",\"url\":\"6.jpeg\"},{\"title\":\"是很好\",\"url\":\"7.jpeg\"}]}";

NSDictionary *infoDic = [self dictionaryWithJsonString:string];

return infoDic;

}

-(NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {

if (jsonString == nil) {

return nil;

}

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

NSError *err;

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];

if(err)

{

NSLog(@"json解析失败:%@",err);

return nil;

}

return dic;

}

- (NSMutableArray *)modelArray {

if (!_modelArray) {

_modelArray = [NSMutableArray array];

}

return _modelArray;

}

- (void)createCollectionView{

UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc]init];

layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

layout.minimumLineSpacing = 0;

layout.minimumInteritemSpacing = 0;

_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, imageHeight * SCREEN_RATE) collectionViewLayout:layout];

_collectionView.tag = 11;

_collectionView.backgroundColor = [UIColor colorWithRed:186 / 255.0 green:186 / 255.0 blue:186 / 255.0 alpha:0.9];

_collectionView.dataSource = self;

_collectionView.delegate = self;

_collectionView.bounces = NO;

_collectionView.alwaysBounceHorizontal = YES;

_collectionView.alwaysBounceVertical = NO;

_collectionView.showsHorizontalScrollIndicator = NO;

_collectionView.showsVerticalScrollIndicator = NO;

[self.view addSubview:_collectionView];

[_collectionView registerClass:[imageCell class] forCellWithReuseIdentifier:imageC];

}

- (void)createRightCollectionView{

LHHorizontalPageFlowlayout * layout = [[LHHorizontalPageFlowlayout alloc] initWithRowCount:kRowCount itemCountPerRow:kItemCountPerRow];

[layout setColumnSpacing:0 rowSpacing:0 edgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)];

layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

// UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];

// layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

layout.minimumLineSpacing = 0;

layout.minimumInteritemSpacing = 0;

_moreCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 300, [UIScreen mainScreen].bounds.size.width, imageHeight * SCREEN_RATE * kRowCount) collectionViewLayout:layout];

_moreCollectionView.backgroundColor = [UIColor clearColor];

_moreCollectionView.tag = 22;

_moreCollectionView.dataSource = self;

_moreCollectionView.delegate = self;

_moreCollectionView.bounces = NO;

_moreCollectionView.alwaysBounceHorizontal = YES;

_moreCollectionView.alwaysBounceVertical = NO;

_moreCollectionView.backgroundColor = [UIColor colorWithRed:186 / 255.0 green:186 / 255.0 blue:186 / 255.0 alpha:0.9];

_moreCollectionView.showsHorizontalScrollIndicator = NO;

_moreCollectionView.showsVerticalScrollIndicator = NO;

[self.view addSubview:_moreCollectionView];

[_moreCollectionView registerClass:[imageCell class] forCellWithReuseIdentifier:moreImageC];

}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

return self.modelArray.count;

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

CollModel * model = self.modelArray[indexPath.row];

imageCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:imageC forIndexPath:indexPath];

cell.itemModel = model;

return cell;

}

// 返回每个item的大小

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

CGFloat CWidth = imageHeight * SCREEN_RATE;

CGFloat CHeight = imageHeight * SCREEN_RATE;

return CGSizeMake(CWidth, CHeight);

}

#pragma mark - UICollectionViewDelegate点击事件

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

CollModel * model = self.modelArray[indexPath.row];

NSLog(@"self.appModelArray----%@",model.title);

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

2、自定义UICollectionViewFlowLayout

LHHorizontalPageFlowlayout.h 实现

#import <UIKit/UIKit.h>

@interface LHHorizontalPageFlowlayout : UICollectionViewFlowLayout

/** 列间距 */

@property (nonatomic, assign) CGFloat columnSpacing;

/** 行间距 */

@property (nonatomic, assign) CGFloat rowSpacing;

/** collectionView的内边距 */

@property (nonatomic, assign) UIEdgeInsets edgeInsets;

/** 多少行 */

@property (nonatomic, assign) NSInteger rowCount;

/** 每行展示多少个item */

@property (nonatomic, assign) NSInteger itemCountPerRow;

//固定宽度

@property (nonatomic, assign) CGFloat itemWidth; //设置完这个,就会自动计算列间距

//固定高度

@property (nonatomic, assign) CGFloat itemHight;//设置完这个,就会自动计算行间距

/** 所有item的属性数组 */

@property (nonatomic, span) NSMutableArray *attributesArrayM;

/** 设置行列间距及collectionView的内边距 */

- (void)setColumnSpacing:(CGFloat)columnSpacing rowSpacing:(CGFloat)rowSpacing edgeInsets:(UIEdgeInsets)edgeInsets;

/** 设置多少行及每行展示的item个数 */

- (void)setRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow;

#pragma mark - 构造方法

/** 设置多少行及每行展示的item个数 */

+ (instancetype)horizontalPageFlowlayoutWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow;

/** 设置多少行及每行展示的item个数 */

- (instancetype)initWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow;

@end

LHHorizontalPageFlowlayout.m 实现

#import "LHHorizontalPageFlowlayout.h"

@implementation LHHorizontalPageFlowlayout

#pragma mark - Public

- (void)setColumnSpacing:(CGFloat)columnSpacing rowSpacing:(CGFloat)rowSpacing edgeInsets:(UIEdgeInsets)edgeInsets

{

self.columnSpacing = columnSpacing;

self.rowSpacing = rowSpacing;

self.edgeInsets = edgeInsets;

}

- (void)setRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow

{

self.rowCount = rowCount;

self.itemCountPerRow = itemCountPerRow;

}

#pragma mark - 构造方法

+ (instancetype)horizontalPageFlowlayoutWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow

{

return [[self alloc] initWithRowCount:rowCount itemCountPerRow:itemCountPerRow];

}

- (instancetype)initWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow

{

self = [super init];

if (self) {

self.rowCount = rowCount;

self.itemCountPerRow = itemCountPerRow;

}

return self;

}

#pragma mark - 重写父类方法

- (instancetype)init

{

self = [super init];

if (self) {

[self setColumnSpacing:0 rowSpacing:0 edgeInsets:UIEdgeInsetsZero];

}

return self;

}

/** 布局前做一些准备工作 */

- (void)prepareLayout

{

[super prepareLayout];

if (self.attributesArrayM && self.attributesArrayM.count > 0) {

[self.attributesArrayM removeAllObjects];

}

// 从collectionView中获取到有多少个item

NSInteger itemTotalCount = [self.collectionView numberOfItemsInSection:0];

// 遍历出item的attributes,把它添加到管理它的属性数组中去

for (int i = 0; i < itemTotalCount; i++) {

NSIndexPath *indexpath = [NSIndexPath indexPathForItem:i inSection:0];

UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexpath];

[self.attributesArrayM addObject:attributes];

}

}

/** 计算collectionView的滚动范围 */

- (CGSize)collectionViewContentSize

{

// 计算出item的宽度

CGFloat itemWidth = (self.collectionView.frame.size.width - self.edgeInsets.left - self.itemCountPerRow * self.columnSpacing) / self.itemCountPerRow;

// 从collectionView中获取到有多少个item

NSInteger itemTotalCount = [self.collectionView numberOfItemsInSection:0];

// 理论上每页展示的item数目

NSInteger itemCount = self.rowCount * self.itemCountPerRow;

// 余数(用于确定最后一页展示的item个数)

NSInteger remainder = itemTotalCount % itemCount;

// 除数(用于判断页数)

NSInteger pageNumber = itemTotalCount / itemCount;

// 总个数小于self.rowCount * self.itemCountPerRow

if (itemTotalCount <= itemCount) {

pageNumber = 1;

}else {

if (remainder == 0) {

pageNumber = pageNumber;

}else {

// 余数不为0,除数加1

pageNumber = pageNumber + 1;

}

}

CGFloat width = 0;

// 考虑特殊情况(当item的总个数不是self.rowCount * self.itemCountPerRow的整数倍,并且余数小于每行展示的个数的时候)

if (pageNumber > 1 && remainder != 0 && remainder < self.itemCountPerRow) {

width = self.edgeInsets.left + (pageNumber - 1) * self.itemCountPerRow * (itemWidth + self.columnSpacing) + remainder * itemWidth + (remainder - 1)*self.columnSpacing + self.edgeInsets.right;

}else {

width = self.edgeInsets.left + pageNumber * self.itemCountPerRow * (itemWidth + self.columnSpacing) - self.columnSpacing + self.edgeInsets.right;

}

// 只支持水平方向上的滚动

return CGSizeMake(width, 150);

}

/** 设置每个item的属性(主要是frame) */

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

{

// item的宽高由行列间距和collectionView的内边距决定

CGFloat itemWidth = (self.collectionView.frame.size.width) / self.itemCountPerRow;

CGFloat itemHeight = (self.collectionView.frame.size.height) / self.rowCount;

NSInteger item = indexPath.item;

// 当前item所在的页

NSInteger pageNumber = item / (self.rowCount * self.itemCountPerRow);

NSInteger x = item % self.itemCountPerRow + pageNumber * self.itemCountPerRow;

NSInteger y = item / self.itemCountPerRow - pageNumber * self.rowCount;

// 计算出item的坐标

CGFloat itemX = itemWidth * x;

CGFloat itemY = itemHeight * y;

UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];

// 每个item的frame

attributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);

return attributes;

}

/** 返回collectionView视图中所有视图的属性数组 */

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect

{

return self.attributesArrayM;

}

#pragma mark - Lazy

- (NSMutableArray *)attributesArrayM

{

if (!_attributesArrayM) {

_attributesArrayM = [NSMutableArray array];

}

return _attributesArrayM;

}

@end

4、自定义cell 和model

model

#import <Foundation/Foundation.h>

@interface CollModel : NSObject

@property (nonatomic,span)NSString *imgUrl;

@property (nonatomic,span)NSString *title;

@property (nonatomic,span)NSString *url;

@end

cell 自定义

#import "imageCell.h"

// 屏幕比例

#define SCREEN_RATE ([UIScreen mainScreen].bounds.size.width/375.0)

@interface imageCell()

@property (nonatomic, span) UIImageView *itemIcon;

@end

@implementation imageCell

@synthesize itemModel = _itemModel;

- (instancetype)initWithFrame:(CGRect)frame{

if (self = [super initWithFrame:frame]) {

self.contentView.backgroundColor = [UIColor clearColor];

[self initView];

}

return self;

}

- (void)initView{

_itemIcon = [[UIImageView alloc] init];

[self.contentView addSubview:_itemIcon];

_itemIcon.backgroundColor = [UIColor clearColor];

CGFloat iconWidth = 80 * SCREEN_RATE;

_itemIcon.frame = CGRectMake(0, 0, iconWidth, iconWidth);

_itemIcon.center = self.contentView.center;

}

- (CollModel *)itemModel{

return _itemModel;

}

- (void)setItemModel:(CollModel *)itemModel

{

if (!itemModel) {

return;

}

_itemModel = itemModel;

[self setCellWithModel:_itemModel];

}

- (void)setCellWithModel:(CollModel *)itemModel{

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

_itemIcon.image = [UIImage imageNamed:itemModel.url];

}];

}

下载:ios uicollectionview横向滚动

GitHub下载

以上是 ios uicollectionview实现横向滚动 的全部内容, 来源链接: utcz.com/z/354540.html

回到顶部