iOS UICollectionLayout 自定义

前言

一般有两种类型的 collection view 布局:

1.独立于内容的布局计算。这正是你所知道的像 UITableView 和 UICollectionViewFlowLayout 这些情况。每个 cell 的位置和外观不是基于其显示的内容,但所有 cell 的显示顺序是基于内容的顺序。可以把默认的 flow layout 做为例子。每个 cell 都基于前一个 cell 放置(或者如果没有足够的空间,则从下一行开始)。布局对象不必访问实际数据来计算布局。

2.基于内容的布局计算。我们的日历视图正是这样类型的例子。为了计算显示事件的起始和结束时间,布局对象需要 直接访问 collection view 的数据源。在很多情况下,布局对象不仅需要取出当前可见 cell 的数据,还需要从所有记录中取出一些决定当前哪些 cell 可见的数据。

(以上摘自objc中国的一篇文章)

仔细思考之后,我发现自定义flowlayout满足不了我的需求,所以选择2的方式,通过自定义layout来解决需求



基于系统layout自定义一个,如下

@interface xxxLayout : UICollectionViewLayout

.m里主要的三个方法是如下

A- (void)prepareLayout;  //  这个其实可以省,实现可以写去第三个里面
B- (CGSize)collectionViewContentSize;
C-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;  //  草率的话,这里返回yes就可以了。具体是个告诉layout要不要重新布局的方法

前两个字面理解就是他的用处,第三个比较费解,其实就是return一个存了UICollectionViewLayoutAttributes对象的数组,

UICollectionViewLayoutAttributes对象更费解,其实直译过来就可以知道,就是告诉布局对象如何布局的东西,当然知道以下三个方法就彻底明白了

1- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
2- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
3- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;

以上三个方法点进-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;就能看到,就在这个下面

到目前,虽然没有任何实现,先梳理以下流程。大致就是 A写算法,B写collectionView的区间,C写cell,supplementary view的实现,而123是根据需求创建,创建123的对象之后,可以给他们一些属性定义,然后存一个数组,让C返回

以上是一些逻辑,看不懂也没事,下面是简单的实现。

- (CGSize)collectionViewContentSize {
    CGFloat contentWidth = self.collectionView.bounds.size.width;
    CGFloat contentHeight = self.collectionView.bounds.size.height;

    CGSize contentSize = CGSizeMake(contentWidth, contentHeight);

    return contentSize;  //  给collectionView一个contentsize而已
}
//  self.attributeArray是我写的一个nsarray的属性,存UICollectionViewLayoutAttributes对象而已-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{

    NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:0];  //  现在没有表头什么的概念,因为都是自定义的,我只要section=0的位置一个表头就这样写他的位置
    UICollectionViewLayoutAttributes *supplementaryViewAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
    [self.attributeArray addObject:supplementaryViewAttributes];

    return self.attributeArray;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
//看清楚,这个是类方法,和123不一样    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath];  
    if ([elementKind isEqualToString:UICollectionElementKindSectionHeader]) {
        attributes.frame = CGRectMake(0, 0, kWidth, 50);
    }
    return attributes;
}

到这里,你的界面应该就有了一个表头了,去collectionView里,和往常一样,写datasource和delegate方法吧

如果要cell的话,就是调用1,我这里仅仅把2列出来作为例子。

时间: 2024-12-17 12:17:45

iOS UICollectionLayout 自定义的相关文章

[IOS]swift自定义uicollectionviewcell

刚刚接触swift以及ios,不是很理解有的逻辑,导致某些问题.这里分享一下swift自定义uicollectionviewcell 首先我的viewcontroller不是直接继承uicollectionviewcontroller,而是添加的uicollectionview到我的storyboard, 然后再新建一个swift的文件,让这个swift继承uicollectionviewcell import Foundation class SVGCell :UICollectionView

iOS多线程自定义operation加载图片 不重复下载图片

摘要:1:ios通过抽象类NSOperation封装了gcd,让ios的多线程变得更为简单易用:   2:耗时的操作交给子线程来完成,主线程负责ui的处理,提示用户的体验   2:自定义operation继承自NSOperation,在子线程中下载图片: 3:保证图片只下载一次,还有保证下载任务不重复 ------------------------------------------------------------------------------------ 实现原理:1:图片缓存:用

IOS 实现自定义的导航栏背景以及自定义颜色的状态栏(支持7.0以及低版本)

为尊重文章原作者,转载务必注明原文地址:http://www.cnblogs.com/wt616/p/3784717.html 先看效果图: 在自定义导航栏背景时,可能会遇到以下一些问题: 1.当设置导航栏背景后,状态栏的颜色也会跟着一起改变掉,这可能不是你说希望看到的 2.IOS7以上的版本和低版本显示出来的导航栏高度位置有差别,这个差别就是状态栏的高度20,为了兼容低版本,必须统一 解决思路: 1.不正常的是状态栏的背景也一起变了,而状态栏的文字是可以通过其他API去设置的:如 [[UIAp

iOS 7 自定义Back按钮 与 Pop interactive gesture

1.自定义Back按钮 iOS中很多时候我们都会自定义返回按钮,也是一件easy的事,类似如下: // 返回按钮 1 - (void)showNavBackButton 2 { 3 UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; 4 [backButton addTarget:self action:@selector(backButtonAction:) 5 forControlEvents:UICont

ios 实现自定义状态栏StatusBar 和 导航栏navigationBar 的状态和颜色

很多app中可以看到不同与导航栏的状态栏的颜色,他妈的真绕嘴. 一.更改状态栏颜色 (StatusBar) 就是比如导航栏是红色的状态栏是绿色的. 要实现这样的效果其实很简单,就是添加一个背景view. 简单的实现过程如下: 1 // 设置导航颜色 可用 2 [self.navigationController.navigationBar setBarTintColor:[UIColor redColor]]; 3 //创建一个高20的假状态栏 4 UIView *statusBarView =

IOS开发自定义CheckBox控件

IOS本身没有系统的CheckBox组件,但是实际开发中会经常用到,所以专门写了一个CheckBox控件,直接上代码 效果图: UICheckBoxButton.h文件如下: #import #import "Common.h" @interface UICheckBoxButton : UIControl { UILabel *label; UIImageView *icon; BOOL checked; id delegate; } @property (retain, nonat

【转】IOS版本自定义字体步骤

本文转载自:http://quick.cocoachina.com/wiki/doku.php?id=ios%E7%89%88%E6%9C%AC%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AD%97%E4%BD%93%E6%AD%A5%E9%AA%A4 比如字体文件名叫abc.ttf, 用mac字体工具查到字体的名称: PostScript名称 FZYHJW--GB1-0 全名 方正艺黑简体 这个PostScript 名称就是我们的字体名称,

iOS开发-自定义后台显示图片(iOS7-Background Fetch的应用)

之前在用电池医生的时候, 发现它有这样一个功能:当应用进入后台的时候, 会显示另外一张图片覆盖App Switcher显示的界面. 效果如下: 变成----> 而这样的一个功能, 对于保护用户隐私还是挺有用的. 这就涉及到了Background Fetch的使用.当然, Background Fetch有更多,更有用的功能, 详见-->iOS 7学习:多任务处理之Background Fetch 下面就介绍下后台图片切换的实现. 1.程序配置后台模式 操作如下: 2. AppDelegate.

iOS开发- 自定义遮罩视图(引导, 功能说明)源码+解析

iOS开发- 自定义遮罩视图(引导, 功能说明)源码+解析 我们平时使用App的时候, 经常在第一次使用的时候, 会有类似"新手教程"之类的东西, 来引导我们应该如何使用这个App. 但是这个"新手教程"不同于常规的引导页(引导页指第一次打开App时候, 弹出的那种介绍视图. 他是静态的, 不需要与用户交互, 可以直接一页页翻, 或者直接跳过.)所谓的"新手教程", 就是按照App的提示, 一步步跟着完成. 那这个"新手教程"