iOS:UICollectionView纯自定义的布局:堆叠式布局、圆式布局 (一般用来制作相册)

集合视图的自动布局:UICollectionViewLayout是抽象根类,必须用它的子类才能创建实例,下面是重写的方法,计算item的布局属性

//每一次重新布局前,都会准备布局(苹果官方推荐使用该方法进行一些初始化)

-(void)prepareLayout

//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性(流式布局内部已经帮助完成)

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

//是否要重新刷新布局(只要显示的item边界发生改变就重新布局)

//只要每一次重新布局内部就会调用下面的layoutAttributesForElementsInRect:获取所有cell(item)的属性

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

//返回需要重新布局的所有item的属性

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect

??下面的这两个布局可以直接带走使用,不需要做任何其他的操作,欧耶

堆叠式布局代码如下:

CustomStackLayout.h

#import <UIKit/UIKit.h>

@interface CustomStackLayout : UICollectionViewLayout

@end

CustomStackLayout.m

#import "CustomStackLayout.h"

#define RANDOM_0_1  arc4random_uniform(100)/100.0

/*
 由于CustomStackLayout是直接继承自UICollectionViewLayout的,父类没有帮它完成任何的布局,因此,
 需要用户自己完全重新对每一个item进行布局,也即设置它们的布局属性UICollectionViewLayoutAttributes
*/

@implementation CustomStackLayout

//重写shouldInvalidateLayoutForBoundsChange,每次重写布局内部都会自动调用
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{

    return YES;
}

//重写collectionViewContentSize,可以让collectionView滚动
-(CGSize)collectionViewContentSize
{
    return CGSizeMake(400, 400);
}

//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //创建布局实例
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    //设置布局属性
    attrs.size = CGSizeMake(100, 100);
    attrs.center = CGPointMake(self.collectionView.frame.size.width*0.5, self.collectionView.frame.size.height*0.5);

    //设置旋转方向
    //int direction = (i % 2 ==0)? 1: -1;

    NSArray *directions = @[@0.0,@1.0,@(0.05),@(-1.0),@(-0.05)];

    //只显示5张
    if (indexPath.item >= 5)
    {
        attrs.hidden = YES;
    }
    else
    {
        //开始旋转
        attrs.transform = CGAffineTransformMakeRotation([directions[indexPath.item]floatValue]);

        //zIndex值越大,图片越在上面
        attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item;
    }

    return attrs;
}

//重写layoutAttributesForElementsInRect,设置所有cell的布局属性(包括item、header、footer)
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *arrayM = [NSMutableArray array];
    NSInteger count = [self.collectionView numberOfItemsInSection:0];

    //给每一个item创建并设置布局属性
    for (int i = 0; i < count; i++)
    {
        //创建item的布局属性
        UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];

         [arrayM addObject:attrs];
    }
    return arrayM;
}

@end

圆式布局代码如下:

CustomCircleLayout.h

#import <UIKit/UIKit.h>

@interface CustomCircleLayout : UICollectionViewLayout

@end

CustomCirclelayout.m

#import "CustomCircleLayout.h"

@implementation CustomCircleLayout

//重写shouldInvalidateLayoutForBoundsChange,每次重写布局内部都会自动调用
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    //创建布局实例
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    //设置item的大小
    attrs.size = CGSizeMake(50, 50);

    //设置圆的半径
    CGFloat circleRadius = 70;

    //设置圆的中心点
    CGPoint circleCenter = CGPointMake(self.collectionView.frame.size.width*0.5, self.collectionView.frame.size.height *0.5);

    //计算每一个item之间的角度
    CGFloat angleDelta = M_PI *2 /[self.collectionView numberOfItemsInSection:indexPath.section];

    //计算当前item的角度
    CGFloat angle = indexPath.item * angleDelta;

    //计算当前item的中心
    CGFloat x = circleCenter.x + cos(angle)*circleRadius;
    CGFloat y = circleCenter.y - sin(angle)*circleRadius;

    //定位当前item的位置
    attrs.center = CGPointMake(x, y);

    //设置item的顺序,越后面的显示在前面
    attrs.zIndex = indexPath.item;

    return attrs;
}

//重写layoutAttributesForElementsInRect,设置所有cell的布局属性(包括item、header、footer)
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *arrayM = [NSMutableArray array];
    NSInteger count = [self.collectionView numberOfItemsInSection:0];

    //给每一个item创建并设置布局属性
    for (int i = 0; i < count; i++)
    {
        //创建item的布局属性
        UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];

        [arrayM addObject:attrs];
    }
    return arrayM;
}

@end

堆叠式布局演示:                                               圆式布局演示:

        

时间: 2024-08-12 12:11:43

iOS:UICollectionView纯自定义的布局:堆叠式布局、圆式布局 (一般用来制作相册)的相关文章

iOS:UICollectionView纯自定义的布局:瀑布流布局

创建瀑布流有三种方式: 第一种方式:在一个ScrollView里面放入三个单元格高度一样的tableView,禁止tableView滚动,只需让tableView随着ScrollView滚动即可.这种方式太奇葩,不太推荐使用... 第二种方式:在一个ScrollView里面从左到右依次放入三个UIView,当ScrollView滚动时,如果之前的三个view消失就将它们存入自定义的缓冲池,即数组中,下拉时再从数组中取出这三个view放到之前三个view位置的下面.但是,切记,每次要依次计算补全最

Flutter 布局类组件:流式布局(Wrap和Flow)

前言 把超出屏幕显示范围会自动折行的布局称为流式布局.Flutter中通过Wrap和Flow来支持流式布局,将Row换成Wrap后溢出部分则会自动折行. Wrap 接口描述 Wrap({ Key key, this.direction = Axis.horizontal, this.alignment = WrapAlignment.start, // 主轴方向子widget的间距 this.spacing = 0.0, // 纵轴方向的对齐方式 this.runAlignment = Wrap

常见的布局实现,以及响应式布局技巧。

布局实现采用何种方式实现布局设计,也有不同的方式,这里基于页面的实现单位而言,分为四种类型:固定布局.可切换的固定布局.弹性布局.混合布局. 固定布局:以像素作为页面的基本单位,不管设备屏幕及浏览器宽度,只设计一套尺寸: 可切换的固定布局:同样以像素作为页面单位,参考主流设备尺寸,设计几套不同宽度的布局.通过识别的屏幕尺寸或浏览器宽度,选择最合适的那套宽度布局: 弹性布局:以百分比作为页面的基本单位,可以适应一定范围内所有尺寸的设备屏幕及浏览器宽度,并能完美利用有效空间展现最佳效果: 混合布局:

iOS UICollectionView 纯代码,无xib

// 1)  必须使用下面的方法进行Cell类的注册: //    - (void)registerClass:forCellWithReuseIdentifier: //    - (void)registerClass:forSupplementaryViewOfKind:withReuseIdentifier: //    - (void)registerNib:forCellWithReuseIdentifier: //    - (void)registerNib:forSupplem

推荐12个创建响应式布局的优秀网格框架

在这篇文章中,我们为大家推荐12个创建响应式布局的优秀网格框架.如果网页设计和开人员采用了正确的工具集,并基于一个灵活的网格架构,以及能够把响应图像应用到到设计之中,那么创建一个具备响应式的网站并不一定是一项艰巨的任务.enjoy! 您可能感兴趣的相关文章 Web 前端开发人员和设计师必读文章集锦 十个拥有丰富 UI 组件的 JavaScript 框架 十款精心挑选的在线 CSS3 代码生成工具 开发者必备的八个最佳云端集成开发环境 2012年度最佳 Web 前端开发工具和框架 Pure Pur

响应式布局这件小事

讲到响应式布局, 相信大家都有一定的了解,响应式布局是今年很流行的一个设计理念,随着移动互联网的盛行,为解决如今各式各样的浏览器分辨率以及不同移动设备的显示效果, 设计师提出了响应式布局的设计方案.今天就和大家来讲讲响应式布局这件小事,包含什么是响应式布局.响应式布局的优点和缺点以及响应式布局该怎么设计(通 过CSS3 Media Query实现响应布局). 一.什么是响应式布局? 响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端—

css3媒体查询实现网站响应式布局

响应式建筑设计.响应式家具设计.响应式办公设计,这些词可能是已有的专业名词,也可能是我自己想出来的一些名词.因为在生活中,我们常常会见到很多让人惊叹的设计,为什么同一套东西经过不同的方式变化之后会给人不同的使用感受和体验呢?这样既节约制造成本,又节省空间,还能体验创意性的生活. 先来给大家欣赏几张图大黄蜂: 沙发床: 没错!大黄蜂为应对紧急战斗而瞬间由汽车变为战斗机,沙发床.沙发座椅是我们见过再平常不过的家具了.我们总是惊叹外国人为什么有这么丰富的想象力和神奇的创造力.而是什么驱动他们去想象进而

14.5-全栈Java笔记:java.awt这些布局怎么写?|流式|边界|网格

布局管理器 读者会发现,如果使用坐标定位法(空布局),在一个比较复杂的界面上定位每个控件的坐标是一个非常麻烦的工作,而且在界面大小发生改变时,控件的绝对位置也不会随之发生改变.那么如果我们想让用户界面上的组件可以按照不同的方式进行排列怎么办?例如:可以依序水平排列,或者按网格方式进行排列等,其实每种排列方案都是指组件的一种"布局",要管理这些布局,就需要本节学习的布局管理器. 管理布局的类由java.awt包来提供,布局管理器是一组实现java.awt.LayoutManager接口的

响应式布局与弹性布局基础篇

响应式布局与弹性布局 一.响应式布局 1.响应式布局的概念 响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端--而不是为每个终端做一个特定的版本.这个概念是为解决移动互联网浏览而诞生的. 响应式布局可以为不同终端的用户提供更加舒适的界面和更好的用户体验,而且随着目前大屏幕移动设备的普及,用"大势所趋"来形容也不为过.随着越来越多的设计师采用这个技术,我们不仅看到很多的创新,还看到了一些成形的模式. 2.响应式布局的实现 2