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

简介:

介绍

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

产品中的一些实现效果

8e10cfb039b894c9d4b8b2e7f0921a2d.png

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

d4af338b6438da160c7d8fb6555c5ff9.png

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

39e70d0a53d8e25b511a94daca7aa2ea.png

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

collection

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

模块图如下:

c35e08cb7d460773d512bd651172bd53.png

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
AI 代码解读

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
AI 代码解读

collectoinViewDelegate

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

@protocol WWCollectionViewDelegate // indexPath元素被选中(void)collectionView:(WWCollectionView )collectionView didSelectItemAtIndexPath:(NSIndexPath )indexPath;// 是否支持选中(BOOL)collectionView:(WWCollectionView )collectionView shouldSelectItemsAtIndexPaths:(NSIndexPath )indexPath;@end
AI 代码解读

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
AI 代码解读

@implementation WWFlowCollectionViewLayout// 横向布局的实现
AI 代码解读

(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;
AI 代码解读

}
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
AI 代码解读
目录
相关文章
|
3月前
|
UED
「Mac畅玩鸿蒙与硬件40」UI互动应用篇17 - 照片墙布局
本篇将带你实现一个简单的照片墙布局应用,通过展示多张图片组成照片墙效果,用户可以点击图片查看其状态变化。
182 67
|
3月前
「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件
本篇将带你实现一个自定义天气预报组件。用户可以通过选择不同城市来获取相应的天气信息,页面会显示当前城市的天气图标、温度及天气描述。这一功能适合用于动态展示天气信息的小型应用。
170 38
|
10月前
|
实现一个自定义的iOS动画效果
【4月更文挑战第9天】本文将详细介绍如何在iOS平台上实现一个自定义的动画效果。我们将通过使用Core Animation框架来实现这个动画效果,并展示如何在不同的场景中使用它。文章的目标是帮助读者理解如何使用Core Animation框架来创建自定义动画,并提供一个简单的示例代码。
87 1
|
4月前
|
UED
「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件
本篇将带你实现一个自定义评分星级组件,用户可以通过点击星星进行评分,并实时显示评分结果。为了让界面更具吸引力,我们还将添加一只小猫图片作为评分的背景装饰。
114 6
「Mac畅玩鸿蒙与硬件23」鸿蒙UI组件篇13 - 自定义组件的创建与使用
自定义组件可以帮助开发者实现复用性强、逻辑清晰的界面模块。通过自定义组件,鸿蒙应用能够提高代码的可维护性,并简化复杂布局的构建。本篇将介绍如何创建自定义组件,如何向组件传递数据,以及如何在不同页面间复用这些组件。
85 5
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
100 1
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
84 5
实现一个自定义的iOS动画效果
本文介绍如何使用Swift和UIKit在iOS应用中实现一个自定义按钮动画,当按钮被点击时,其颜色从蓝色渐变为绿色,形状从圆形变为椭圆形,释放后恢复原状。通过UIView动画方法实现这一效果,代码示例展示了动画的平滑过渡和状态切换,有助于提升应用的视觉体验和用户交互。
80 1
iOS自动化测试方案(五):保姆级VMware虚拟机安装MacOS
详细的VMware虚拟机安装macOS Big Sur的保姆级教程,包括下载VMware和macOS镜像、图解安装步骤和遇到问题时的解决方案,旨在帮助读者顺利搭建macOS虚拟机环境。
299 3
iOS自动化测试方案(五):保姆级VMware虚拟机安装MacOS
iOS页面布局:UIScrollView的布局问题
iOS页面布局:UIScrollView的布局问题
133 8

热门文章

最新文章

  • 1
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 2
    iOS|解决 setBrightness 调节屏幕亮度不生效的问题
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 5
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
  • 6
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 7
    iOS各个证书生成细节
  • 8
    恶意软件盯上Mac:利用苹果安全工具发起攻击
  • 9
    iOS|记一名 iOS 开发新手的前两次 App 审核经历
  • 10
    为什么有了MAC还需要IP?