欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

ios的collection控件的自定义布局实现与设计

程序员文章站 2023-12-17 10:32:16
collection控件用来实现界面的各种自定义布局,最常用其作为横向、竖向的布局控件。很早之前,系统对于collection的支持并不是很好。所以自己实现了支持自定义布局...

collection控件用来实现界面的各种自定义布局,最常用其作为横向、竖向的布局控件。很早之前,系统对于collection的支持并不是很好。所以自己实现了支持自定义布局、自定义cell的collection控件。自定义的collection可以满足所有的产品特殊需求及动态效果,例如在某些特殊情况下可能需要除选中cell之外的其它cell执行布局动画等。在collection的基础之上,我又实现了支持cell拖动、拖离窗体的tabview控件。本文主要介绍自定义collection的设计与实现,后续持续更新多tab的tabview控件。

我有几张阿里云幸运券分享给你,用券购买或者升级阿里云相应产品会有特惠惊喜哦!把想要买的产品的幸运券都领走吧!快下手,马上就要抢光了。

产品中的一些实现效果

ios的collection控件的自定义布局实现与设计

mac旺旺表情面板,实现grid与横向布局

ios的collection控件的自定义布局实现与设计

mac千牛工作台用作横向布局

ios的collection控件的自定义布局实现与设计

ios千牛历史登录页面实现当前选中cell变大并且选中cell总中最中位置校准动效的效果

collection

collection主要包括:继承scrollview的collectionview,数据源协议collectionviewdatasource,事件响应协议collectoinviewdelegate,布局基类collectoinlayout以及展示单元collectioncellview。

模块图如下:

ios的collection控件的自定义布局实现与设计

 collectionview

collection容器包含指实现collectionviewdatasource、collectoinviewdelegate协议的指针以及collectoinlayout成员,同时维护collectoincellview的控件重用。

@interface wwcollectionview : nsscrollview
// 布局对象
@property (retain) wwcollectionviewlayout *layout;
// 数据源
@property (weak) id datasource;
// 事件响应
@property (weak) id delegate;
// 重加载数据
(void)reloaddata;
// 重排布
(void)invalidatelayout;
// 取消返回选中
(void)unselectedall;
// 注册重用对象
(void)registerclass:(class)cellclass forcellwithreuseidentifier:(nsstring *)identifier;
// 对象重用
(id)dequeuereusablecellwithreuseidentifier:(nsstring )identifier forindexpath:(nsindexpath )indexpath;
// 设置选中对象
(void)selectitematindexpath:(nsindexpath *)indexpath animated:(bool)animated;
// 当前选中对象
(nsindexpath *)selecteditem;
// 重加载indexpath item
(void)reloaditemsatindexpath:(nsindexpath *)indexpath;
// 插入
(void)insertitemsatindexpath:(nsindexpath *)indexpath withanimate:(bool)animate;
// 删除
(void)deleteitemsatindexpath:(nsindexpath *)indexpath withanimate:(bool)animate;
// 重新排列
(void)relayoutwithanimation:(bool)animated completion:(void (^)(bool finished))completion;
// 滚动到apoint
(void)scrolltopoint:(nspoint)apoint withanimate:(bool)animate;
@end

collectionviewdatasource

collection展示的数据源,由宿主实现。

@protocol wwcollectionviewdatasource 
// 返回indexpath下标的cell
(wwcollectioncellview )collectview:(wwcollectionview )collectionview cellforitematindexpath:(nsindexpath *)indexpath;
// 总cell个数
(nsinteger)numberofitemincollectionview:(wwcollectionview *)collectionview;
// cell的数据
(id)collectionview:(wwcollectionview )colletionview objectvalueatindexpath:(nsindexpath )indexpath;
@end

collectoinviewdelegate

collection事件的回调响应,由宿主实现。

@protocol wwcollectionviewdelegate 
// indexpath元素被选中
(void)collectionview:(wwcollectionview )collectionview didselectitematindexpath:(nsindexpath )indexpath;
// 是否支持选中
(bool)collectionview:(wwcollectionview )collectionview shouldselectitemsatindexpaths:(nsindexpath )indexpath;
@end

collectoinlayout

collectioncellview的布局方案。

@interface wwcollectionviewlayout : nsobject
// 布局基类
@property (weak) wwcollectionview *collectionview;
// 每个cell元素大小
@property (assign) nssize itemsize;
// edgeinsets
@property (assign) nsedgeinsets edgeinsets;
// scrollview使用,表示整个画布大小
@property (assign) nssize viewcontentsize;
(instancetype)initwithcollectionview:(wwcollectionview *)collectionview;
(void)invalidatelayout;
// 返回index的cell大小
(nsrect)frameforindexpath:(nsindexpath *)index total:(nsinteger)total;
(nssize)collectionviewcontentsize;
@end
// 横向布局控件
@interface wwflowcollectionviewlayout : wwcollectionviewlayout
@property (assign) cgfloat headmargin;
@property (assign) cgfloat tailmargin;
@end
// grid布局控件
@interface wwgridcollectionviewlayout : wwcollectionviewlayout
// 每行多少个
@property (assign) nsinteger numberperrow;
@property (assign) cgfloat headmargin;
@property (assign) cgfloat tailmargin;
@end
@implementation wwflowcollectionviewlayout
(void)invalidatelayout {
nsinteger cellcount = [self.collectionview.datasource numberofitemincollectionview:self.collectionview];
cgrect bounds = self.collectionview.bounds;
// 画布宽度
cgfloat width = _headmargin + _tailmargin + (cellcount - 1) (self.edgeinsets.left + self.edgeinsets.right) + self.itemsize.width cellcount;
if (width < bounds.size.width) {
width = bounds.size.width;
}
self.viewcontentsize = nsmakesize(width, bounds.size.height);
[super invalidatelayout];
}
(nsrect)frameforindexpath:(nsindexpath *)index total:(nsinteger)total {
cgfloat leftpos = self.headmargin + [index indexatposition:0] * (self.itemsize.width + self.edgeinsets.left + self.edgeinsets.right);
// 返回cell的rect
return nsmakerect(leftpos, self.edgeinsets.top, self.itemsize.width, self.itemsize.height);
}
@end

collectoincellview

collection展示的cell控件。

@interface wwcollectioncellview : nsview
// 当前cell被选中
@property (nonatomic, assign) bool selected;
// 数据
@property (nonatomic, retain) id datavalue;
// 使用前重置展示效果
(void)reset;
@end

上一篇:

下一篇: