mac、iOS端支持自定义布局的collection控件的实现与设计

介绍

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

产品中的一些实现效果

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

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

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

collection

collection主要包括:继承scrollview的collectionView,数据源协议collectionViewDataSource,事件响应协议collectoinViewDelegate,布局基类collectoinLayout以及展示单元collectionCellView。

模块图如下:

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
时间: 2024-10-26 19:00:38

mac、iOS端支持自定义布局的collection控件的实现与设计的相关文章

Android获取dialog自定义布局中的控件

public class PopUpDialog extends Dialog { Context context; private View customView; public PopUpDialog(Context context) { super(context); this.context = context; // TODO Auto-generated constructor stub } public PopUpDialog(Context context, int theme)

Android自定义View之组合控件实现类似电商app顶部栏_Android

本文实例为大家分享了Android自定义View之组合控件,仿电商app顶部栏的相关代码,供大家参考,具体内容如下 效果图: 分析:左右两边可以是TextView和Button,设置drawableTop即可,中间的看着像是EditText,但是用过淘宝天猫等类似app的话会发现点击搜索不是在当前Activit进行搜索的,是跳转到另外的页面进行的,所以用TextView然后设置背景即可. 实现流程 参数列表: 设置属性文件:values下建立attrs.xml文件,添加需要自定义的属性. <?x

Android自定义下拉刷新控件RefreshableView_Android

这是在了解下拉刷新功能原理下的产物,下拉刷新可以说是国产APP里面必有的功能,连Google都为此出了SwipeRefreshLayout,一种MD风格的下拉刷新. 不过,MD风格在国内似乎很是艰难,不单单是国内系统主流仍是4.4的原因,也有用户习惯的问题,扯的有点多了,在看了许多博客之后,我突然想写一个能仿照 SwipeRefreshLayout 的兼容所有控件的下拉刷新,不单单只是 ListView,希望它也可以包容普通的View和ScrollView,经过两天的奋斗,终于搞定了,因为我的目

Android自定义View之组合控件实现类似电商app顶部栏

本文实例为大家分享了Android自定义View之组合控件,仿电商app顶部栏的相关代码,供大家参考,具体内容如下 效果图: 分析:左右两边可以是TextView和Button,设置drawableTop即可,中间的看着像是EditText,但是用过淘宝天猫等类似app的话会发现点击搜索不是在当前Activit进行搜索的,是跳转到另外的页面进行的,所以用TextView然后设置背景即可. 实现流程 参数列表: 设置属性文件:values下建立attrs.xml文件,添加需要自定义的属性. <?x

一个比较通用的分页控件,完整的设计时支持和比较流行的分页模式(提供源码下载)

这是我写的一个分页控件,功能如下: 1.支持设计时支持和两种分页模式,其中综合分页模式的效果如下: 普通分页模式的效果如下: 2.完善的设计时支持,包括自动套用格式和设计时面板设置: 使用方法: 在aspx页面中:复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Cyclone.Custom

imageview-Android中怎么让一个布局中所有控件都获得这个布局的点击状态

问题描述 Android中怎么让一个布局中所有控件都获得这个布局的点击状态 我在一个线性布局中有一个ImageView和一个TextView,怎么设置点击这个线性布局的时候ImageView处于选取状态,还有selector怎么设置 解决方案 你可以在这个layout的点击事件中,设置ImageView的setPressed(true),这样就可以在selector中因公pressed的设置了 解决方案二: 我想你正需要它们: setDuplicateParentStateEnabled 子控件

CYQ.Data 支持WPF相关的数据控件绑定(2013-08-09)

事件的结果 经过多天的思考及忙碌的开发及测试,CYQ.Data 终于在UI上全面支持WPF,至此,CYQ.Data 已经可以方便支持wpf的开发,同时,框架仍保留最低.net framework2.0版本的支持. 支持WPF的起因: CYQ.Data 一直是基于2.0语法下支持开发的框架,在未直接支持WPF之前,对于控件列表的绑定,因为WPF竟然不支持DataTable,研究后发现需要从MDataTable.ToDataTable().DefaultView来转一次绑定:另外对于UI控件,也只能

android 像贴吧这种如何布局 需要哪些控件 和技术 请讲解下

问题描述 android 像贴吧这种如何布局 需要哪些控件 和技术 请讲解下 解决方案 e开头的那个listview,官方组件,你直接敲,会出来一个E后面是listview,验证的英文没记住 解决方案二: 你确定你要在app上做成这样子? relativelayout linearLayout listview imageview textview 这些控件就够了 解决方案三: 我仿佛看到了嵌套嵌套嵌套- 解决方案四: 两个listview 嵌套操作就可以.可以搜索安卓评论功能demo.我记得有

Android自定义滑动接听电话控件组实例_Android

本文根据组件开发思想,首先介绍android自定义控件,然后将自定义的控件封装为jar包.最为实现滑动接听电话控件组. 一.目录结构 二.运行效果 三.代码实现 首先,自定义一个类IncomingPhone继承RelativeLayout public IncomingPhone(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; TextView textView = new Tex