首页 > 系统 > iOS > 正文

ios uicollectionview实现横向滚动

2020-07-26 01:29:06
字体:
来源:转载
供稿:网友

现在使用卡片效果的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, strong) UICollectionView * collectionView;@property (nonatomic, strong) NSMutableArray * modelArray;@property (nonatomic, strong) 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, strong) 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,strong)NSString *imgUrl;@property (nonatomic,strong)NSString *title;@property (nonatomic,strong)NSString *url;@end

cell 自定义

#import "imageCell.h"// 屏幕比例#define SCREEN_RATE  ([UIScreen mainScreen].bounds.size.width/375.0)@interface imageCell()@property (nonatomic, strong) 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下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表