UICollectionView之自定义Layout
#import <UIKit/UIKit.h>
@interface WQViewController : UIViewController
- (id)initWithFrame:(CGRect)frame;
@end
#import "WQViewController.h"
#import "WQCollectionViewController.h"
#import "WQCollectionViewCircleLayout.h"
@interface WQViewController ()
@end
@implementation WQViewController
- (id)initWithFrame:(CGRect)frame {
if (self == [super init]) {
self.view.frame = frame;
self.view.backgroundColor = [UIColor yellowColor];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
WQCollectionViewCircleLayout *circleLayout = [[WQCollectionViewCircleLayout alloc] init];
WQCollectionViewController *collectionVC = [[WQCollectionViewController alloc] initWithCollectionViewLayout:circleLayout];
[self addChildViewController:collectionVC];
[self.view addSubview:collectionVC.collectionView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
~~~~~~~~~~~~~~~~~~~~~~~
#import <UIKit/UIKit.h>
@interface WQCollectionViewController : UICollectionViewController
@end
#import "WQCollectionViewController.h"
#import "WQCollectionViewCircleLayout.h"
#import "WQCollectionViewCell.h"
@interface WQCollectionViewController ()
@property (assign, nonatomic) NSInteger cellCount;
@end
@implementation WQCollectionViewController
static NSString * const reuseIdentifier = @"Cell";
- (void)viewDidLoad {
[super viewDidLoad];
_cellCount = 8;
self.collectionView.frame = [UIScreen mainScreen].bounds;
self.collectionView.backgroundColor = [UIColor whiteColor];
[self.collectionView registerClass:[WQCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
[self.collectionView addGestureRecognizer:tapGesture];
}
#pragma mark - UITapGesture
- (void)handleTapGesture:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
CGPoint initiailPinchPoint = [sender locationInView:self.collectionView];
NSIndexPath *tapCellPath = [self.collectionView indexPathForItemAtPoint:initiailPinchPoint];
if (tapCellPath != nil) {
[self.collectionView performBatchUpdates:^{
self.cellCount = self.cellCount - 1;
[self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:tapCellPath]];
} completion:^(BOOL finished) {
[self.collectionView reloadData];
}];
} else {
[self.collectionView performBatchUpdates:^{
self.cellCount = self.cellCount + 1;
[self.collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:(random()%self.cellCount) inSection:0]]];
} completion:^(BOOL finished) {
[self.collectionView reloadData];
}];
}
}
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _cellCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
WQCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
[cell updateAppreanceAccrodingToItem:indexPath.item];
cell.contentView.backgroundColor = [UIColor redColor];
cell.contentView.layer.cornerRadius = 20;
cell.contentView.layer.masksToBounds = YES;
// UILabel *lbl = [[UILabel alloc] init];
// lbl.center = cell.contentView.center;
// lbl.text = [NSString stringWithFormat:@"%ld", indexPath.item];
// [lbl sizeToFit];
// [cell.contentView addSubview:lbl];
//
return cell;
}
#pragma mark <UICollectionViewDelegate>
/*
// Uncomment this method to specify if the specified item should be highlighted during tracking
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
*/
/*
// Uncomment this method to specify if the specified item should be selected
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
*/
/*
// Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
return NO;
}
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
}
*/
@end
~~~~~~~~~~~~~~~~~~~~~~~~
#import <UIKit/UIKit.h>
@interface WQCollectionViewCell : UICollectionViewCell
- (void)updateAppreanceAccrodingToItem:(NSInteger)item;
@end
#import "WQCollectionViewCell.h"
@interface WQCollectionViewCell ()
@property(strong, nonatomic)UILabel *lbl;
@end
@implementation WQCollectionViewCell
-(void)prepareForReuse {
_lbl.text = nil;
}
- (void)updateAppreanceAccrodingToItem:(NSInteger)item {
self.lbl.text = [NSString stringWithFormat:@"%ld", item];
[self addSubview:self.lbl];
}
- (UILabel *)lbl {
if (_lbl == nil) {
_lbl = [[UILabel alloc] init];
[_lbl setFont:[UIFont systemFontOfSize:12.0f]];
_lbl.textAlignment = NSTextAlignmentCenter;
_lbl.frame = CGRectMake(10, 10, 20, 20);
}
return _lbl;
}
@end
~~~~~~~~~~~~~~~~~~~~~自定义layout
#import <UIKit/UIKit.h>
@interface WQCollectionViewCircleLayout : UICollectionViewLayout
@end
#define ITEM_SIZE 40.0f
#import "WQCollectionViewCircleLayout.h"
@interface WQCollectionViewCircleLayout ()
@property(assign, nonatomic) NSInteger cellCount;
@property(assign, nonatomic) CGPoint center;
@property(assign, nonatomic) CGFloat radius;
@property(strong, nonatomic) NSMutableArray *indexPathToAnimation;
@end
@implementation WQCollectionViewCircleLayout
- (void)prepareLayout {
[super prepareLayout];
CGSize size = self.collectionView.frame.size;
_cellCount = [self.collectionView numberOfItemsInSection:0];
_center = CGPointMake(size.width/2.0f, size.height/2.0f);
// _radius = MIN(size.width/2.5f, size.height/2.5f);
_radius = 120;
}
- (CGSize)collectionViewContentSize {
return self.collectionView.frame.size;
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *attributes = [NSMutableArray array];
for (int i = 0; i < _cellCount; i ++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
return attributes;
}
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
CGRect oldBounds = self.collectionView.bounds;
if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds) || CGRectGetHeight(newBounds) != CGRectGetWidth(oldBounds)) {
return YES;
}
return NO;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
layoutAttributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
layoutAttributes.center = CGPointMake(_center.x + _radius * cosf(2*indexPath.item*M_PI / _cellCount), _center.y + _radius * sinf(2*indexPath.item*M_PI / _cellCount));
NSLog(@"%@", NSStringFromCGRect(layoutAttributes.frame));
return layoutAttributes;
}
-(void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems {
[super prepareForCollectionViewUpdates:updateItems];
NSMutableArray *attrsArray = [NSMutableArray array];
for (UICollectionViewUpdateItem *updateItem in updateItems) {
switch (updateItem.updateAction) {
case UICollectionUpdateActionInsert:
{
NSIndexPath *itemIndex = updateItem.indexPathAfterUpdate;
[attrsArray addObject:itemIndex];
}
break;
case UICollectionUpdateActionDelete:
{
NSIndexPath *itemIndex = updateItem.indexPathBeforeUpdate;
[attrsArray addObject:itemIndex];
}
break;
case UICollectionUpdateActionMove:
{
NSIndexPath *itemIndexBeforeUpdate = updateItem.indexPathBeforeUpdate;
NSIndexPath *itemIndexAfterUpdate = updateItem.indexPathAfterUpdate;
[attrsArray addObject:itemIndexBeforeUpdate];
[attrsArray addObject:itemIndexAfterUpdate];
}
break;
case UICollectionUpdateActionReload:
break;
case UICollectionUpdateActionNone:
break;
default:
break;
}
}
_indexPathToAnimation = attrsArray;
}
-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
UICollectionViewLayoutAttributes *layoutAttr = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
if ([_indexPathToAnimation containsObject:itemIndexPath]) {
layoutAttr.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(0.2, 0.2), M_PI);
layoutAttr.center = CGPointMake(self.collectionView.center.x, self.collectionView.bounds.size.height);
// layoutAttr.center = CGPointMake(CGRectGetMidX(self.collectionView.bounds), CGRectGetMidY(self.collectionView.bounds));
[self.indexPathToAnimation removeObject:itemIndexPath];
}
return layoutAttr;
}
@end
~~~~~~~~~~~~~实现效果:



UICollectionView之自定义Layout的更多相关文章
- UICollectionView Layout自定义 Layout布局
from: http://www.tuicool.com/articles/vuyIriN 当我们使用系统自带的UICollectionViewFlowLayout无法实现我们的布局时,我们就可以 ...
- 自定义 Layout布局 UICollectionViewLayout
from: http://www.tuicool.com/articles/vuyIriN 当我们使用系统自带的UICollectionViewFlowLayout无法实现我们的布局时,我们就可以 ...
- 一个UICollectionView自定义layout的实现
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @ ...
- UICollectionView的水平流水布局自定义layout
最近做合创共美的商城项目,遇到发货地址的不配送地区,是做一个弹出框,弹出框的布局是根据地名字数长短不齐的标签. 本来也可以用tableview来做的.只不过多建几个tableviewcell就可以了. ...
- log4net 自定义Layout日志字段
最近在使用log4net的时候有一个简单的需求,就是自定义个格式化输出符.这个输出符是专门用来帮我记录下业务ID.业务类型的.比如,“businessID:328593,businessType: o ...
- UICollectionview实现自定义cell的移动删除
今天 ,有群里人询问了 ,支付宝首页的UICollectionview 的cell(其实不能成为cell,应该是item,不过大家习惯这么称呼了)怎么实现 自定义的拖拽 和删除,然后我查了下资料,它的 ...
- 使用纯代码定义UICollectionView和自定义UICollectionViewCell
1.自定义UICollectionView 2.实现<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UICollec ...
- 详细分享UICollectionView的自定义布局(瀑布流, 线性, 圆形…)
前言: 本篇文章不是分享collectionView的详细使用教程, 而是属于比较’高级’的collectionView使用技巧, 阅读之前, 我想你已经很熟悉collectionView的基本使用, ...
- 安卓自定义控件(四)实现自定义Layout
本来我是不准备写这篇文章的,我实在想不出有什么样奇怪的理由,会去继承ViewGroup然后自定义一个布局,大概是我的项目经验还不够吧,想了好久,想到了这样一个需求: 需求 如图:在项目中经常有一个这样 ...
随机推荐
- 在ASP.NET Web Forms中使用页面导出伪xls Excel表格
将数据导出为Excel表格是比较常见的需求,也有很多组件支持导出真正的Excel表格.由于Excel能打开HTML文件,并支持其中的table元素以及p之类的文本元素的显示,所以把.html扩展名改为 ...
- 《JS权威指南学习总结--9.5 类和类型》
内容要点: 介绍了三种用以检测任意对象的类的技术,instanceof运算符.constructor属性,以及构造函数的名字. 但每种技术都不甚完美,本节总结了鸭式辩型,这种编程哲学更加关注对象可以完 ...
- 《高性能Javascript》读书笔记-4
第四章 算法和流程控制 代码组织结构和解决具体问题的思路是影响代码性能的主要因素 循环处理是最常见的编程模式之一,也是提高性能的关注点之一 循环分四种:标准for循环 ; i < Things. ...
- 2016弱校联盟十一专场10.2——Around the World
题目链接:Around the World 题意: 给你n个点,有n-1条边,现在这n-1条边又多增加了ci*2-1条边,问你有多少条欧拉回路 题解: 套用best定理 Best Theorem:有向 ...
- MVC3+EF4.1学习系列(八)-----利用Repository and Unit of Work重构项目
项目最基础的东西已经结束了,但是现在我们的项目还不健全 不利于测试 重复性代码多 层与层之间耦合性高 不利于扩展等问题.今天的这章 主要就是解决这些问题的.再解决这些问题时,自己也产生了很多疑 ...
- NOIP2001-普及组复赛-第一题-数的计算
题目描述 Description 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1.不作任何处理; 2.在 ...
- tomcat的事件监听
//事件涉及的三个组件:事件源.事件对象.事件监听器 //一个总的事件监听器接口,所有不同分类的事件监听器都继承这个接口 public interface EventListener {} //例如 ...
- PHP class which generates PDF files from UTF-8 encoded HTML
http://www.mpdf1.com/mpdf/index.php
- Colorful(Folders星语多彩文件夹) v1.7绿色版
软件名称:星语多彩文件夹ColorfulFolders v1.7绿色版软件类别:国产软件运行环境:WinXP/2003/Vista/Win7/Win2008软件语言:简体中文授权方式:免费版软件大小: ...
- 线程池Executors探究
线程池用到的类在java.util.concurrent包下,核心类是Executors,通过其不同的几个方法可产生不同的线程池. 1.生成固定大小的线程池 public static Executo ...