ios 定制UICollectionViewFlowLayout类实现网格布局

Objective—C实现UICollectionView中UICollectionViewCell的重排实现 iOS9.0中UICollectionView的功能进一步得到增强,不仅仅能通过重写layout实现效率更高的瀑布流效果,更增加了对UICollectionViewCell的重排。本文将参考swift2.0实现重排效果实现OC对UICollectionView中Cell得重排。 阅读详情

默认的流式布局会自动换行,以便使区段中的条目能够使用集合视图的长度或宽度,但这样做出来的视图只能在一个方向上滚动。如果愿意多做一些数学运算,就可以编写自定义的布局子类,从而实现不会换行的双向滚动视图。实现该功能所需要的运算律比较大,而且不是特别容易。

完全定制了UICollectionViewFlowLayout的子类,覆写了collectionViewContentSize及layoutAttributesForItemAtIndexPath:方法,以便手工摆放每个条目。这种实现方式完全考虑到所有与间隔有关的请求以及回调方法。相比之下,普通的流式布局只会在满足多个最小值的前提下,试着把条目合适摆放到屏幕上。

typedef NS_ENUM(NSUInteger, GridRowAlignment) {
    GridRowAlignmentNone,
    GridRowAlignmentTop,
    GridRowAlignmentCenter,
    GridRowAlignmentBottom,
};

@interface GridLayout : UICollectionViewFlowLayout

@property (nonatomic,assign) GridRowAlignment aligment;

@end
@implementation GridLayout
- (BOOL)usesIndividualItemSizing
{
    return [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)];
}
- (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize itemSize = self.itemSize;
    if ([self usesIndividualItemSizing]) {
        itemSize = [(id <UICollectionViewDelegateFlowLayout>)self.collectionView.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
    }
    return itemSize;
}

- (BOOL)usesIndividualInsets
{
    return [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)];
}

- (UIEdgeInsets)insetsForSection:(NSInteger)section
{
    UIEdgeInsets insets = self.sectionInset;
    if ([self usesIndividualInsets]) {
        insets = [(id<UICollectionViewDelegateFlowLayout>)self.collectionView.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
    }
    return insets;
}

- (BOOL)usesIndividualItemSpacing
{
    return [self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)];
}

- (CGFloat)itemSpacingForSection:(NSInteger)section
{
    CGFloat spacing = self.minimumInteritemSpacing;
    if ([self usesIndividualItemSpacing]) {
        spacing = [(id <UICollectionViewDelegateFlowLayout>)self.collectionView.delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:section];
    }
    return spacing;
}

- (CGFloat)maxItemHeightForSection:(NSInteger)section
{
    CGFloat maxHeight = 0;
    NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:section];
    for (int i = 0; i< numberOfItems; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:section];
        CGSize itemSize = [self sizeForItemAtIndexPath:indexPath];
        maxHeight = MAX(maxHeight, itemSize.height);
        
    }
    return  maxHeight;
}

- (CGFloat)fullWidthForSection:(NSInteger)section
{
    UIEdgeInsets insets = [self insetsForSection:section];
    CGFloat horizontalInsetExtent = insets.left + insets.right;
    CGFloat collectiveWith = horizontalInsetExtent;
    
    NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:section];
    for (int i = 0; i < numberOfItems; i ++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:section];
        CGSize itemSize = [self sizeForItemAtIndexPath:indexPath];
        collectiveWith += itemSize.width;
        collectiveWith += [self itemSpacingForSection:section];
    }
    
    collectiveWith -= [self itemSpacingForSection:section];
    return collectiveWith;
}

- (CGSize)fullSizeForSection:(NSInteger)section
{
    CGFloat headerExtent = (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) ? self.headerReferenceSize.width : self.headerReferenceSize.height;
    CGFloat footerExtent = (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) ? self.footerReferenceSize.width : self.footerReferenceSize.height;
    UIEdgeInsets insets = [self insetsForSection:section];
    CGFloat verticalInsetExtent = insets.top + insets.bottom;
    CGFloat maxHeight = [self maxItemHeightForSection:section];
    
    CGFloat fullHeight = headerExtent + footerExtent + verticalInsetExtent + maxHeight;
    CGFloat fullWith = [self fullWidthForSection:section];
    return CGSizeMake(fullWith, fullHeight);
}

- (CGFloat)horizontalInsetForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UIEdgeInsets insets = [self insetsForSection:indexPath.section];
    CGFloat horizontalOffset = insets.left;
    for (int i = 0;  i < indexPath.item; i ++) {
        NSIndexPath *indexPath1 = [NSIndexPath indexPathForItem:i inSection:indexPath.section];
        CGSize itemSize = [self sizeForItemAtIndexPath:indexPath1];
        horizontalOffset += (itemSize.width + [self itemSpacingForSection:indexPath.section]);
        
    }
    return horizontalOffset;
}

- (CGFloat)verticalInsetForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize thisItemSize = [self sizeForItemAtIndexPath:indexPath];
    CGFloat verticlOffset = 0;
    for (int i = 0; i < indexPath.section; i ++) {
        verticlOffset += [self fullSizeForSection:i].height;
    }
    CGFloat headerExtent = (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) ? self.headerReferenceSize.width : self.headerReferenceSize.height;
    verticlOffset +=headerExtent;
    
    UIEdgeInsets insets = [self insetsForSection:indexPath.section];
    verticlOffset += insets.top;
    
    CGFloat maxHeigth = [self maxItemHeightForSection:indexPath.section];
    CGFloat fullHeight = (maxHeigth - thisItemSize.height);
    CGFloat midHeight = fullHeight / 2;
    
    switch (self.aligment) {
        case GridRowAlignmentNone:
        case GridRowAlignmentTop:
            break;
        case GridRowAlignmentCenter:
            verticlOffset += midHeight;
            break;
        case GridRowAlignmentBottom:
            verticlOffset += fullHeight;
            break;
            
        default:
            break;
    }
    return verticlOffset;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    CGSize thisItemSize = [self sizeForItemAtIndexPath:indexPath];
    CGFloat verticalOffset = [self verticalInsetForItemAtIndexPath:indexPath];
    CGFloat horizontalOffset = [self horizontalInsetForItemAtIndexPath:indexPath];
    if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
        attributes.frame = CGRectMake(horizontalOffset, verticalOffset, thisItemSize.width, thisItemSize.height);
        
    }else{
        attributes.frame = CGRectMake(verticalOffset, horizontalOffset, thisItemSize.width, thisItemSize.height);
    }
    return attributes;
}

- (CGSize)collectionViewContentSize
{
    NSInteger sections = self.collectionView.numberOfSections;
    
    CGFloat maxWith = 0;
    CGFloat collectiveHeight = 0;
    for (int i=0; i < sections; i++) {
        CGSize sectionSize = [self fullSizeForSection:i];
        collectiveHeight += sectionSize.height;
        maxWith = MAX(maxWith, sectionSize.width);
    }
    
    if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
        return CGSizeMake(maxWith, collectiveHeight);
    }else
    {
        return CGSizeMake(collectiveHeight, maxWith);
    }
}

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attributes = [NSMutableArray array];
    for (NSInteger section = 0; section < self.collectionView.numberOfSections; section++) {
        for (NSInteger item = 0; item < [self.collectionView numberOfItemsInSection:section]; item ++ ) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
            UICollectionViewLayoutAttributes * layout = [self layoutAttributesForItemAtIndexPath:indexPath];
            [attributes addObject:layout];
        }
    }
    return attributes;
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
@end
布局对象要把每个元素的排布位置都计算出来。但是它不会使用行间距属性,因为该属性只在自动换行的前提下才有意义。我们制作的网格状布局,绝不会自动换行,所以会彻底胡洛这个属性。

还有一个名为alignment属性。这个新的属性决定了表格中的每一行是顶端对齐、底端对齐,还是居中对齐。它会查询一整行的总体高度,然后可以会把比这个高度矮的条目移动一段距离。

iOS学习笔记【十一】——UICollectionViewLayout iOS学习笔记——UICollectionViewLayout Summary UITableView 和 UICollectionView 在显示其子视图集的过程中仅扮演容器角色,且对子视图集真正的内容毫不知情。UICollectionView在此之上进行了进一步抽象。它将其子视图的位置,大小和外观的控制权委托给一个单独的布局对象。 布局继承自UICollectionViewLayout 抽象基类。iOS6 中以UICollectionViewFlowLayout类的形式提出了一个具体的布局实现。 / 阅读详情

相关推荐

iOS轻量级网格布局实现与实战详解

当需求超出能力范围时(如瀑布流、环形布局、异形排列),必须继承并重写核心方法。在中可干预动画过程,实现自定义插值曲线或附加视觉效果(如缩放淡入)。综上所述,提供了从简单到复杂的全方位网格实现能力,掌握其架构原理与优化技巧,是打造高品质 iOS 应用的基础。为了确保事件接口的清晰性和可维护性,应首先定义一个专门用于处理点击事件的协议。该协议通常包含点击位置、数据源索引路径以及可能的附加信息参数。// MARK: - Cell点击事件协议上述代码定义了一个名为。

weixin_28235889的博客 976

19、UICollectionView实现自动换行和自动计算collectionView高度

import Foundation //UICollectionView自动换行 /// 对齐方向的枚举, enum AlignDirection: Int { case left = 0, //左对齐 rightFlow, //右对齐 左起显示 rightData, //右对齐 右起显示 center //中间对齐 } class CollectionViewAlignFlowLayout: UICollec

重楼的博客 2347

掌握iOS视图定制:表格与集合视图深度解析

本章节深入探讨了iOS开发中表格视图(table views)和集合视图(collection views)的使用方法和定制技巧。从表格视图的基础结构开始,讲解如何通过数据源和代理来动态管理内容,并通过自定义单元格来实现更复杂的布局。同时,对于集合视图的介绍则着重于其灵活的布局选项和自定义布局的实现,展示了如何在二维空间中自由排列视图元素,以实现网格或任何自定义布局。

weixin_42186015的博客 388

ios 自动换行flowLayout

ios 自动换行flowLayout 子View可像tableview一样通过实现协议添加,可限制最多显示几行

蓝骑的博客 2214

掌握UICollectionView的瀑布流布局:iOS实战指南

本文还有配套的精品资源,点击获取 简介:UICollectionView是iOS中用于展示复杂布局的控件。本教程详细说明如何实现瀑布流布局,包括创建自定义UICollectionViewFlowLayout子类、处理列数和间距、动态调整单元格高度和宽度,并优化性能与用户体验。通过学习本教程,开发者将能熟练掌握UICollectionView的瀑布流效果实现。 1....

weixin_28888459的博客 2111

iOS开发实战:UICollectionView实现瀑布流布局

虽然提供了基础的布局能力,但在实际开发中,往往需要更复杂的布局逻辑。此时,可以通过继承并重写相关方法来实现自定义布局。本章深入讲解了瀑布流布局的三大核心机制:布局属性的动态计算、cell 尺寸的自适应调整、以及布局刷新的触发与优化。通过对和的重写,我们实现了灵活的瀑布流布局;而的合理使用则确保了布局在数据变化时能够及时刷新,同时通过缓存等策略提升性能。下一章将围绕图片异步加载展开,探讨如何进一步优化瀑布流的整体性能与用户体验。

weixin_42163404的博客 1092

UITableView和UICollectionView自动滚动到某一行

//---------------UITableView--------------------- NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:10 inSection:0]; [[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosi...

FIGHTING的专栏 2091

UICollectionView实战示例代码详解

本章系统地讲解了 UICollectionView 的网格布局实现方式,从设计原则出发,分析了固定列数与自适应列宽的实现思路,接着详细演示了如何通过 UICollectionViewFlowLayout 实现基础网格布局,并介绍了使用第三方库实现复杂布局的方案。最后,针对布局性能问题,提出了减少 layoutSubviews 调用、异步加载与绘制优化等实用策略。

weixin_35749786的博客 479

xcode 调用CCCollectionView实现多行多列展示

1. CCCollectionView下载 下载地址:

lengxue789的专栏 2872

iOSUICollectionView实现瀑布流的完整指南

在iOS开发中,是一个非常强大的组件,用于展示大量数据集合的视图。它提供了灵活的布局选项,可以创建复杂的用户界面。本章节将介绍的基本概念、组成部分以及它如何与其他视图组件相互作用。由三个主要部分组成:和。DataSource负责提供数据,Delegate负责处理单元格的交互,而Layout则定义了单元格的尺寸和位置。的一大亮点是它的layout,它允许开发者以声明性方式定义数据如何在屏幕上展现。从简单的网格布局到复杂的瀑布流样式,都能胜任。

weixin_28968525的博客 1000

告别命令行!用这个开源的Web版Kettle工具,5分钟搞定数据集成任务编排

本文介绍了一款开源的Web版Kettle工具,通过直观的拖拽界面大幅提升数据集成效率,告别复杂的命令行操作。该工具基于Kettle核心引擎,支持跨平台协作、轻量化访问和降低学习曲线,特别适合业务分析师快速上手。实测显示,使用该工具后任务配置错误率下降62%,协作效率提升40%。

weixin_30267785的博客 434

【iOS】UICollectionView

UICollectionView是iOS26之后UIKit框架中引入的一个新的控件,用于实现网格布局、横向滚动列表、照片墙、轮播图等复杂布局的强大控件。不再只能垂直滚动,其滚动方向可垂直、水平或自定义。通过UICollectionViewLayout控制进行布局。通过layout布局回调的代理方法可以动态地定制每个item的大小和collection的布局属性。UICollectionView中Item的大小位置可自定义。更加灵活。

2401_87841908的博客 1039

【实战指南】从零构建UNet多分类分割数据集:标注、转换与训练全流程

本文提供了一份从零构建UNet多分类分割数据集的完整实战指南。详细介绍了使用Labelme进行图像标注的核心技巧与规范,并通过Python脚本将标注结果转换为模型可用的VOC格式。最后,指导如何修改经典的PyTorch版UNet代码,以适配自定义数据集并进行训练与测试,帮助读者完成从数据准备到模型训练的全流程。

arduino9maker的博客 286

[转]通过UICollectionView创建网格布局

在这个教程中,我们经构建一个件的程序,以网格布局的俄方式现实图片集,你将学到下面的信息:  UICollectionView简介 如何是使用UICollectionView构建一个简单的基于网格的布局 自定义Collection Cell背景      UICollectionView 基础      UICollectionVi

lin的iOS专栏 1044

还在用iReport 5.6.0?手把手教你用JasperSoft Studio 6.8.0设计报表(附JDK 11+兼容方案)

本文详细介绍了从iReport 5.6.0迁移到JasperSoft Studio 6.8.0的全过程,包括JDK 11+环境配置、项目迁移实战、高级特性应用及常见问题解决方案。帮助开发者高效完成报表生成工具的升级,提升开发体验和报表性能。

weixin_30687051的博客 407

Python量化入门:用pytdx获取800个交易日K线数据的完整指南(附代码)

本文为Python量化交易初学者提供了使用pytdx库免费获取股票日线级别K线数据的完整指南。文章详细介绍了从环境搭建、单只股票数据获取,到构建健壮的批量下载器、数据清洗与验证,再到基础分析与可视化的全流程,并附有可直接运行的代码示例,帮助读者快速建立本地股票数据库。

weixin_29050513的博客 1462

终极指南:iOS瀑布流布局的快速实现方法

想要在iOS应用中创建像Pinterest那样炫酷的瀑布流效果吗?🤩 UICollectionViewFlowLayout是实现这种布局的关键技术!作为一名iOS开发者,掌握瀑布流布局能够让你的应用界面更加生动有趣,用户体验瞬间提升。本教程将带你从零开始,用最简单的方式实现专业的瀑布流布局效果。 ## 什么是瀑布流布局? **瀑布流布局**是一种非对称的网格布局方式,每列的高度不固定,新的项

gitblog_00302的博客 484

Shopee商品详情页反爬实战:手把手逆向x-sap-Ri和x-sap-Sec参数(附完整调试过程)

本文详细解析了Shopee商品详情页反爬机制中的x-sap-Ri和x-sap-Sec参数逆向过程。通过JS逆向技术,从环境数据采集到多层哈希运算,完整拆解了这两个关键参数的生成逻辑,并提供了实战技巧和Node.js实现方案,帮助开发者应对Shopee的动态加密挑战。

weixin_33701251的博客 1596

通过UICollectionView创建网格布局

为什么80%的码农都做不了架构师?>>> ...

weixin_33796205的博客 231

具身大小脑全栈全网独家复现|LLM链式推理+边缘VLA感知+毫秒级运动小脑、优化人形步态僵硬运动滞后、打通思考-行走-操作全链路适配居家工业多场景落地

高层决策大脑(异步10Hz,GPU算力):轻量化机器人微调LLM+RhinoVLA边缘视觉大模型,负责自然语言链式工序拆解、全局环境语义感知、目标物体筛选、跨机器人动作适配,输出粗粒度运动目标,不介入底层伺服计算;依托View Registry实现异构机器人动作对齐,适配多形态机器人切换;中层调度小脑(硬实时1kHz,CPU算力)

qq_36130719的博客 255

uniapp - 详细手机端h5网页调用手机摄像头进行二维码识别扫描,在uniapp的H5移动端微信网页平台中,在浏览器中调用手机扫码功能详细教程,识别二维码并获取扫描结果(完整示例源码,一键复制即用

uniapp,h5,手机端网页,H5手机网页,uniapp开发h5实现扫码功能,uniapp微信h5网页扫码sdk使用教程,uniapp h5网页如何实现浏览器扫码,uniapp扫码功能怎么兼容h5_uniapph5怎么做扫码功能,uniapp的手机网页如何实现扫二维码一维码,浏览器H5实现js扫码,H5调用摄像头和扫一扫功能,亲测可用,H5调用本地摄像头实现扫一扫,uni-h5项目解决扫码功能,uniapp实现微信H5扫码,解决uniapp在H5端使用不能扫码问题,uni-app的h5扫码(二维码、条形码

✅ 精选推荐文章 1万+

IOS 集合视图指南4:使用流布局

Using the Flow Layout(使用流布局) You can arrange items in your collection views using a concrete layout object, the UICollectionViewFlowLayout class. The flow layout implements a line-based break

B9班的真高兴 1668

大数据工程中的数据血缘分析工具比较

数据血缘(Data Lineage)是大数据治理中的核心组成部分,它描述了数据从源头到目标的完整流动路径。系统介绍数据血缘的核心概念和技术原理比较主流开源和商业数据血缘工具的功能特点提供数据血缘分析的实践指南和选型建议本文首先介绍数据血缘的基本概念,然后深入分析其技术原理和实现方法,接着比较主流工具的特点,最后通过实际案例展示应用场景。数据血缘(Data Lineage): 描述数据从源头到目标的完整流动路径,包括所有转换和处理步骤元数据(Metadata)

大数据洞察的博客 900

LXReorderableCollectionViewFlowLayout高级定制教程:滚动触发与动画效果优化

LXReorderableCollectionViewFlowLayout是一个强大的UICollectionViewFlowLayout扩展库,它支持单元格的拖拽重排功能,类似于iBook中长按拖动书籍的交互效果。本教程将深入探讨如何高级定制该库的滚动触发机制和动画效果,帮助开发者打造更流畅、更具吸引力的用户体验。 ## 核心功能概述 LXReorderableCollectionViewF

gitblog_00919的博客 585

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

自定义Collection View布局

自定义Collection View布局 原文:http://www.cocoachina.com/industry/20131122/7401.html 转自answer-huang的博客 原文出自:Custom Collection View Layouts    UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一颗新

落天罐头的博客 414

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

从0到1掌握UICollectionView-Layouts-Kit:StackLayout实现卡片堆叠效果教程

想要为你的iOS应用添加炫酷的卡片堆叠效果吗?📱 UICollectionView-Layouts-Kit中的StackLayout正是你需要的解决方案!这个强大的自定义布局库让开发者能够轻松实现类似实体卡片堆叠的视觉效果,为用户带来沉浸式的交互体验。 ## 🎯 什么是StackLayout卡片堆叠效果? **StackLayout**是UICollectionView-Layouts-K

gitblog_00691的博客 495

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: ios 检查设备距离与电池状态及判断是否是Retina显示屏
下一篇: ios 统一类型标识符
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值