ios uicollectionview實(shí)現(xiàn)橫向滾動(dòng)
現(xiàn)在使用卡片效果的app很多,之前公司讓實(shí)現(xiàn)一種卡片效果,就寫了一篇關(guān)于實(shí)現(xiàn)卡片的文章。文章最后附有demo
實(shí)現(xiàn)上我選擇了使用UICollectionView ;用UICollectionViewFlowLayout來定制樣式;下面看看具體實(shí)現(xiàn)
效果

實(shí)現(xiàn)上我選擇了使用UICollectionView ;用UICollectionViewFlowLayout來定制樣式;下面看看具體實(shí)現(xiàn)
具體實(shí)現(xiàn)
1、ViViewController.m 代碼實(shí)現(xiàn)
#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個(gè)
static const NSInteger kRowCount = 3; //每頁顯示行數(shù)
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;
}
// 返回每個(gè)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點(diǎn)擊事件
- (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 實(shí)現(xiàn)
#import <UIKit/UIKit.h> @interface LHHorizontalPageFlowlayout : UICollectionViewFlowLayout /** 列間距 */ @property (nonatomic, assign) CGFloat columnSpacing; /** 行間距 */ @property (nonatomic, assign) CGFloat rowSpacing; /** collectionView的內(nèi)邊距 */ @property (nonatomic, assign) UIEdgeInsets edgeInsets; /** 多少行 */ @property (nonatomic, assign) NSInteger rowCount; /** 每行展示多少個(gè)item */ @property (nonatomic, assign) NSInteger itemCountPerRow; //固定寬度 @property (nonatomic, assign) CGFloat itemWidth; //設(shè)置完這個(gè),就會(huì)自動(dòng)計(jì)算列間距 //固定高度 @property (nonatomic, assign) CGFloat itemHight;//設(shè)置完這個(gè),就會(huì)自動(dòng)計(jì)算行間距 /** 所有item的屬性數(shù)組 */ @property (nonatomic, strong) NSMutableArray *attributesArrayM; /** 設(shè)置行列間距及collectionView的內(nèi)邊距 */ - (void)setColumnSpacing:(CGFloat)columnSpacing rowSpacing:(CGFloat)rowSpacing edgeInsets:(UIEdgeInsets)edgeInsets; /** 設(shè)置多少行及每行展示的item個(gè)數(shù) */ - (void)setRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow; #pragma mark - 構(gòu)造方法 /** 設(shè)置多少行及每行展示的item個(gè)數(shù) */ + (instancetype)horizontalPageFlowlayoutWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow; /** 設(shè)置多少行及每行展示的item個(gè)數(shù) */ - (instancetype)initWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow; @end
LHHorizontalPageFlowlayout.m 實(shí)現(xiàn)
#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 - 構(gòu)造方法
+ (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;
}
/** 布局前做一些準(zhǔn)備工作 */
- (void)prepareLayout
{
[super prepareLayout];
if (self.attributesArrayM && self.attributesArrayM.count > 0) {
[self.attributesArrayM removeAllObjects];
}
// 從collectionView中獲取到有多少個(gè)item
NSInteger itemTotalCount = [self.collectionView numberOfItemsInSection:0];
// 遍歷出item的attributes,把它添加到管理它的屬性數(shù)組中去
for (int i = 0; i < itemTotalCount; i++) {
NSIndexPath *indexpath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexpath];
[self.attributesArrayM addObject:attributes];
}
}
/** 計(jì)算collectionView的滾動(dòng)范圍 */
- (CGSize)collectionViewContentSize
{
// 計(jì)算出item的寬度
CGFloat itemWidth = (self.collectionView.frame.size.width - self.edgeInsets.left - self.itemCountPerRow * self.columnSpacing) / self.itemCountPerRow;
// 從collectionView中獲取到有多少個(gè)item
NSInteger itemTotalCount = [self.collectionView numberOfItemsInSection:0];
// 理論上每頁展示的item數(shù)目
NSInteger itemCount = self.rowCount * self.itemCountPerRow;
// 余數(shù)(用于確定最后一頁展示的item個(gè)數(shù))
NSInteger remainder = itemTotalCount % itemCount;
// 除數(shù)(用于判斷頁數(shù))
NSInteger pageNumber = itemTotalCount / itemCount;
// 總個(gè)數(shù)小于self.rowCount * self.itemCountPerRow
if (itemTotalCount <= itemCount) {
pageNumber = 1;
}else {
if (remainder == 0) {
pageNumber = pageNumber;
}else {
// 余數(shù)不為0,除數(shù)加1
pageNumber = pageNumber + 1;
}
}
CGFloat width = 0;
// 考慮特殊情況(當(dāng)item的總個(gè)數(shù)不是self.rowCount * self.itemCountPerRow的整數(shù)倍,并且余數(shù)小于每行展示的個(gè)數(shù)的時(shí)候)
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;
}
// 只支持水平方向上的滾動(dòng)
return CGSizeMake(width, 150);
}
/** 設(shè)置每個(gè)item的屬性(主要是frame) */
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
// item的寬高由行列間距和collectionView的內(nèi)邊距決定
CGFloat itemWidth = (self.collectionView.frame.size.width) / self.itemCountPerRow;
CGFloat itemHeight = (self.collectionView.frame.size.height) / self.rowCount;
NSInteger item = indexPath.item;
// 當(dāng)前item所在的頁
NSInteger pageNumber = item / (self.rowCount * self.itemCountPerRow);
NSInteger x = item % self.itemCountPerRow + pageNumber * self.itemCountPerRow;
NSInteger y = item / self.itemCountPerRow - pageNumber * self.rowCount;
// 計(jì)算出item的坐標(biāo)
CGFloat itemX = itemWidth * x;
CGFloat itemY = itemHeight * y;
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
// 每個(gè)item的frame
attributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);
return attributes;
}
/** 返回collectionView視圖中所有視圖的屬性數(shù)組 */
- (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橫向滾動(dòng)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS中讀寫鎖的簡(jiǎn)單實(shí)現(xiàn)方法實(shí)例
讀寫鎖是計(jì)算機(jī)程序的并發(fā)控制的一種同步機(jī)制,也稱“共享-互斥鎖”、多讀者-單寫者鎖,讀操作可并發(fā)重入,寫操作是互斥的,這篇文章主要給大家介紹了關(guān)于iOS中讀寫鎖的簡(jiǎn)單實(shí)現(xiàn)方法,需要的朋友可以參考下2021-11-11
iOS開發(fā)中對(duì)于攝像頭的一些基本使用方法分享
這篇文章主要介紹了iOS開發(fā)中對(duì)于攝像頭的一些基本使用方法分享,包括判斷攝像頭是否可用的方法,需要的朋友可以參考下2015-10-10
Apple?Watch?App?Lifecycle應(yīng)用開發(fā)
這篇文章主要為大家介紹了Apple?Watch?App?Lifecycle應(yīng)用開發(fā)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
實(shí)例講解iOS應(yīng)用UI開發(fā)之基礎(chǔ)動(dòng)畫的創(chuàng)建
這篇文章主要介紹了iOS應(yīng)用UI開發(fā)之基礎(chǔ)動(dòng)畫的創(chuàng)建,以關(guān)鍵幀動(dòng)畫作為重要知識(shí)點(diǎn)進(jìn)行講解,需要的朋友可以參考下2015-11-11
Flutter繪制3.4邊形及多邊形漸變動(dòng)畫實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Flutter繪制3.4邊形之多邊形漸變動(dòng)畫實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
iOS開發(fā)中最基本的位置功能實(shí)現(xiàn)示例
這篇文章主要介紹了iOS開發(fā)中最基本的位置功能實(shí)現(xiàn)示例,需要的朋友可以參考下2015-09-09
iOS中 LGLAlertView 提示框的實(shí)例代碼
這篇文章主要介紹了iOS中 LGLAlertView 提示框的實(shí)例代碼非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09

