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然后自定义一个布局,大概是我的项目经验还不够吧,想了好久,想到了这样一个需求: 需求 如图:在项目中经常有一个这样 ...
随机推荐
- 友元(友元函数、友元类和友元成员函数) C++
有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员. 友元(frend)机制允许一个类将 ...
- ZOJ 2476 Total Amount
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2476 Time Limit: 2 Seconds ...
- Dokan[转]
原文地址:http://www.cnblogs.com/xxonehjh/p/3634889.html 因工作需要,最近与同事合作使用Dokan开发了一个虚拟磁盘的简单程序,初步实现了远程目录映射到本 ...
- 关于wcf中一些重要词语解释
From a distant view, the service offers an
- visual studio2013 apache cordova基于web的跨平台应用
目前在研究微软的visual studio 2013开发跨平台的android.ios.windows phone.当然是基于html javascript css的web跨平台app. 在visua ...
- XML 用途
XML 用途 XML 应用于 Web 开发的许多方面,常用于简化数据的存储和共享. XML 把数据从 HTML 分离 如果您需要在 HTML 文档中显示动态数据,那么每当数据改变时将花费大量的时间来编 ...
- mysql表设计---时间类型
mysql 时间格式的区别 datetime 日期 +时间timestamp 时间戳 格式都是一样YYYY-MM-DD HH:MM:SS int(12)型存储php的time()时间戳,格式10位14 ...
- jquery之全选全不选
<input type="checkbox" onclick="selall(this)" />全选/全不选 <input type=&quo ...
- #if defined和#if !defined(c语言的宏定义)
我们要检查a是否定义 #if defined a #undef a #define a 200 #endif 上述语句检验a是否被定义,如果被定义,则用#undef语句解除定义,并重新定义a为200 ...
- HDU 2614 Beat(DFS)
题目链接 Problem Description Zty is a man that always full of enthusiasm. He wants to solve every kind o ...