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然后自定义一个布局,大概是我的项目经验还不够吧,想了好久,想到了这样一个需求: 需求 如图:在项目中经常有一个这样 ...
随机推荐
- BeautifulSoup抓取列表页锚文本
素闻BeautifulSoup提取效率低,艾玛,第一印象果然是很要命的,反正比Re 和 Lxml 是要慢的,不过就无奈Re的正则折腾来折腾去,没写出来,Lxml 的 Xpath 又用得不好. 不过就这 ...
- Linux用户相关的操作命令
1.建用户: adduser phpq //新建phpq用户 passwd phpq //给phpq用户设置密码 2.建工作组 groupadd test //新建 ...
- Java和R齐头并进才是根本
Java和R齐头并进才是根本 数据分析师的成长之路 http://www.slideshare.net/SanderMak/data-science-with-r-for-java-d
- Swift逃逸闭包之见解
Swift 逃匿闭包顾名思义,就是闭包想要逃跑.当闭包作为参数传给一个方法时,在这个方法被调用完后闭包却还没有被执行,而是等到方法执行完后才调用 基本都是跨线程的时候才会有逃逸闭包这个说法.因为异步 ...
- jQuery第四章
jQuery中的事件和动画 一.jQuery中的事件 1.加载DOM (1)执行时机 $(document).ready()方法和window.onload方法有相似的功能,但是在执行时机方面是有区别 ...
- MAC img 安装 mysql 修改密码
参考 : http://tieba.baidu.com/p/3042628829 step1: 苹果->系统偏好设置->最下边点mysql 在弹出页面中 关闭mysql服务(点击stop ...
- tableview 详解I
在开发iphone的应用时基本上都要用到UITableView,这里讲解一下UITableView的使用方法及代理的调用情况 UITableView使用详解 - (void)viewDidLoad { ...
- 怎么查看window7的.net framework的版本
第一步.打开控制面板,在大图标查看方式下,点击“程序和功能” 第二步.在程序和功能界面,点击左侧“打开或关闭Windows功能” 第三步.在打开或关闭Windows功能界面,通过拖动滚动条的方式,找到 ...
- easyui-datagrid加载时的效率低下,解决方案
在360浏览器中 使用easyui datagrid 加载数据是效率低下,有时候会出现卡机. 可以修改easyui源码进行解决.
- 关于const *和 * const
int main() { ; ; int const *p = &i; p = &j; *p = ; //错误,*p的值被const修饰,为只读变量,不可更改 int * const ...