UICollectionView新特性

本文介绍了一个使用UICollectionView实现的圆形布局示例。通过自定义CircleLayout类,实现了触摸非圆周部分增加Cell,触摸圆周上的Cell则删除对应Cell的功能。此外,还介绍了如何自定义UICollectionViewCell并展示了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

针对IOS6提出的全新特性UICollectionView做了一个实际的使用,有很多地方还是很有意义的,定制化貌似更加的灵活了,这样对于大量的自定义来说更是“万事俱备,东风已来”矣。在Apple Developer 中心也有Demo,那个Demo也是很有意思的,文章最后会给出下载地址。

一、战果展示,呵呵~~


实现了一个圆形的UICollectionView的使用,当触摸非圆周的部分时,Cell会增加,这里注意每个小图片就是一个cell;当触摸圆周上的cell,也就是小图片的时候,对应的cell就会消除。至于中间那个,嘿嘿~~是实现的一个gif效果显示。这里分享一个IOS设备上实现gif效果图的图片获取方法。将一张gif图片在MAC机上使用系统自带的“预览”打开,就可以看到一张一张的图片了。然后按照顺序“另存为”即可拿到顺序的图片了。接下来就可以参照   ios上实现gif显示效果 这里进行设置了。祝愉快~~~

二、代码分析

 1.1 代理方法介绍(AppDelegate)

在AppDelegate里面,方法didFinishLaunchingWithOption中,创建ViewController,这个Controller是继承自UICollectionViewController的,并且初始化controller的使用需要制定Controller的Layout,这个Layout就是制定CollectionView里面的cells和supplementary views的。

样例代码:

[cpp]  view plain copy
  1. #import "AppDelegate.h"  
  2.   
  3. #import "ViewController.h"  
  4. #import "CircleLayout.h"  
  5.   
  6. @implementation AppDelegate  
  7.   
  8. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
  9. {  
  10.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
  11.     // Override point for customization after application launch.  
  12.     self.viewController = [[ViewController alloc] initWithCollectionViewLayout:[[CircleLayout alloc] init]];  
  13.     self.window.rootViewController = self.viewController;  
  14.     [self.window makeKeyAndVisible];  
  15.     return YES;  
  16. }  
  1.2 自定义Layout类介绍(CircleLayout)

在上面代码中,可以看到引入了一个类CircleLayout.h ,这个类的作用就是指定页面的Layout样式的。从结果图上可以看到,这个类里面至少要实现cell的样式、collectionView的样式。要实现的东西不少~~~

CircleLayout类是继承自UICollectionViewLayout的,而UICollectionViewLayout类是一个抽象基类,通过继承它可以生成collectionView的Layout信息。而Layout的作用就是决定CollectionView中的Cell、supplementary view、decoration view的位置的。在使用UICollectionViewLayout的时候,必须谨记“先子类化,后使用” !

   1.2.1 子类化

在子类化UICollectionViewLayout的时候,需要注意:

aa  Layout只负责布局样式,而不负责创建view。(view的创建是通过代理方法 datasource来实现的)

bb  Layout对象中定义了view的位置以及view大小size的信息

   1.2.2 UICollectionView 的三要素介绍

CellsLayout就像一个管理者,而cell就是被管理者,每一个cell代表了collectionview中的一个item,一个collectionview可以放在一个section中,也可以放在整个UICollectionview中。使用和位置都是由Layout对象定义的。

Supplementary Views纯属显示的一个要素,不能被用户选择,而且还是可有可无的。只要你想为Section或者整个collection view 添加页眉和页脚,它就是了。

Decoration Views一个装饰品,不可被用户选择,类似于Supplementary View,使用和位置都是由Layout定义的。可有可无。

   1.2.3  需要重载的方法介绍

每一个管理者(Layout对象)都有自己的一套方法,来管理手下的虾兵小将:

1. collectionViewContentSize    

2.  shouldInvalidateLayoutForBoundsChange:

3.  layoutAttributesForElementsInRect:

4.  layoutAttributesForItemAtIndexPath:

5. layoutAttributesForSupplementaryViewOfKind:atIndexPath: (如果layout 支持 supplementary views)

6.layoutAttributesForDecorationViewWithReuseIdentifier:atIndexPath: (如果layout 支持 decoration views)

上述方法的具体含义和作用,可参考  SDK

   1.2.4 折腾“插入”和"删除 "

当collection view 中的数据发生了变化,例如其中的item有了变化,collection view 都需要重新检索相应的Layout信息,来得到新的显示。这样collection view 就有了自己的一套检索的方法,你只需要进行重载就可以了。

  • initialLayoutAttributesForInsertedItemAtIndexPath:
  • initialLayoutAttributesForInsertedSupplementaryElementOfKind:atIndexPath:
  • finalLayoutAttributesForDeletedItemAtIndexPath:
  • finalLayoutAttributesForDeletedSupplementaryElementOfKind:atIndexPath:


    但是这里只需要进行简单的实现,所以只需要重载一下两个方法:

  • initialLayoutAttributesForInsertedItemAtIndexPath:
  • finalLayoutAttributesForDeletedItemAtIndexPath:

         OK,这就是自定义的CircleLayout类中需要注意的。下来上code:

    CircleLayout.h 文件:

     
    [cpp]  view plain copy
    1. #import <UIKit/UIKit.h>  
    2.   
    3. @interface CircleLayout : UICollectionViewLayout  
    4.   
    5. //定义圆的圆心、半径,以及cell的个数  
    6.   
    7. @property (nonatomic,assign) CGPoint center;  
    8. @property (nonatomic,assign) CGFloat radius;  
    9. @property (nonatomic,assign) NSInteger cellCount;  
    10.   
    11. @end  

    CircleLayout.m文件:

    [cpp]  view plain copy
    1. #import "CircleLayout.h"  
    2.   
    3. //定义item的大小  
    4. #define ITEM_SIZE 70  
    5.   
    6. @implementation CircleLayout  
    7.   
    8. //为创建Circle做准备  
    9. - (void)prepareLayout{  
    10.     [super prepareLayout];  
    11.       
    12.     CGSize size = self.collectionView.frame.size;  
    13.     _cellCount = [[self collectionView] numberOfItemsInSection:0];  
    14.     _center = CGPointMake(size.width / 2.0, size.height / 2.0);  
    15.     _radius = MIN(size.width, size.height) / 2.5;  
    16. }  
    17.   
    18. //设置collectionViewContentsize  
    19. - (CGSize) collectionViewContentSize{  
    20.     return self.collectionView.frame.size;  
    21. }  
    22.   
    23. //设置UICollectionViewLayoutAttributes  
    24. - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{  
    25.     UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];  
    26.     attributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);  
    27.     attributes.center = CGPointMake(_center.x + _radius * cosf(2 * indexPath.item * M_PI / _cellCount),  
    28.                                     _center.y + _radius * sinf(2 * indexPath.item * M_PI / _cellCount));  
    29.       
    30.     return attributes;  
    31. }  
    32.   
    33. //设置layoutAttributesForElementsInRect  
    34. - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{  
    35.     NSMutableArray *attributes = [NSMutableArray array];  
    36.     for(NSInteger i = 0; i < self.cellCount; i++){  
    37.         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];  
    38.         [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];  
    39.     }  
    40.     return attributes;  
    41. }  
    42.   
    43. #pragma mark --  
    44. #pragma mark  Layout init  & final  
    45.   
    46. //复写initialLayoutAttributesForInsertedItemAtIndexPath  
    47. - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForInsertedItemAtIndexPath:(NSIndexPath *)itemIndexPath  
    48. {  
    49.     UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];  
    50.     attributes.alpha = 0.0;  
    51.     attributes.center = CGPointMake(_center.x, _center.y);  
    52.     return attributes;  
    53. }  
    54.   
    55. //复写finalLayoutAttributesForDeletedItemAtIndexPath  
    56.   
    57. - (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDeletedItemAtIndexPath:(NSIndexPath *)itemIndexPath  
    58. {  
    59.     UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];  
    60.     attributes.alpha = 0.0;  
    61.     attributes.center = CGPointMake(_center.x, _center.y);  
    62.     attributes.transform3D = CATransform3DMakeScale(0.1, 0.1, 1.0);  
    63.     return attributes;  
    64. }  
    65. @end  

      1.3  自定义Cell

    关于UITableViewCell的自定义,估计大多数人都会不止一种的自定义方法吧,UICollectionViewCell也可以定制,这样就极大的方便了那些需要震撼性UI的App开发者的使用了。UICollectionViewCell的主要功能就是管理collectionview中的每一个item了,注意只是当item在屏幕的可视范围的时候,OK,那么自定义的这个Cell就直接继承自UICollectionViewCell类,在这个自定义的Cell中需要一个图像容器UIImageView来存放每一个item上的图片。

         

    [cpp]  view plain copy
    1. #import <UIKit/UIKit.h>  
    2.   
    3. @interface CircleCell : UICollectionViewCell  
    4.   
    5. @property (nonatomic,strong) UIImageView *imageView;  
    6.   
    7. @end  

    [cpp]  view plain copy
    1. #import "CircleCell.h"  
    2. #import <QuartzCore/QuartzCore.h>  
    3.   
    4. @implementation CircleCell  
    5.   
    6. @synthesize imageView;  
    7.   
    8. - (id)initWithFrame:(CGRect)frame  
    9. {  
    10.     self = [super initWithFrame:frame];  
    11.     if (self) {  
    12.         // Initialization code  
    13.         self.contentView.layer.cornerRadius = 10.0f;  
    14.         self.contentView.frame = CGRectMake(0, 0, 75, 75);  
    15.         self.contentView.layer.borderWidth = 1.0f;  
    16.         self.contentView.layer.borderColor = [UIColor whiteColor].CGColor;  
    17.         self.contentView.backgroundColor = [UIColor underPageBackgroundColor];  
    18.           
    19.         self.imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1_120103225810_1.jpeg"]];  
    20.         self.imageView.layer.masksToBounds = YES;  
    21.         self.imageView.layer.cornerRadius = 10.0f;  
    22.         self.imageView.frame = self.contentView.frame;  
    23.         [self.contentView addSubview:self.imageView];  
    24.           
    25.     }  
    26.     return self;  
    27. }   
    28. @end  

    完成之后,就完成了大部分的code准备工作了。接下来就是要在开始那个ViewController类中进行调用使用了。

      三、最终的code

    首先要实现UICollectionView的两个代理方法:delegate   &  dataSource。并且要给collectionView 添加Tap 手势哦,这样才能让用户在触摸的时候有所交互。

      直接上code吧。HOHO~~

     ViewController.h 文件:

    [cpp]  view plain copy
    1. #import <UIKit/UIKit.h>  
    2.   
    3. @interface ViewController : UICollectionViewController  
    4.   
    5. @property (nonatomic,assign)NSInteger cellCount;  
    6.   
    7. @end  

    ViewController.m 文件:

    [cpp]  view plain copy
    1. #import "ViewController.h"  
    2. #import "GifLayoutView.h"  
    3. #import "CircleCell.h"  
    4.   
    5. @interface ViewController ()  
    6.   
    7. @end  
    8.   
    9. @implementation ViewController  
    10.   
    11. - (void)viewDidLoad  
    12. {  
    13.     [super viewDidLoad];   
    14.     // Do any additional setup after loading the view, typically from a nib.   
    15.       
    16.     //添加背景gif显示图View  
    17.     GifLayoutView *gifView = [[GifLayoutView alloc]initWithFrame:CGRectMake(0, 0, 350, 350)];  
    18.     gifView.center = self.collectionView.center;  
    19.     [self.collectionView addSubview:gifView];  
    20.       
    21.     //为collectionView添加tapGesture,并注册。  
    22.     self.cellCount = 20;  
    23.     UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];  
    24.     [self.collectionView addGestureRecognizer:tapGesture];  
    25.     [self.collectionView registerClass:[CircleCell class] forCellWithReuseIdentifier:@"Circle_Cell"];  
    26.     [self.collectionView reloadData];  
    27.     self.collectionView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];  
    28.        
    29. }  
    30.   
    31. //设置numberOfItemsInSection  
    32. - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;  
    33. {  
    34.     return self.cellCount;  
    35. }  
    36.   
    37. //复用Cell  
    38. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath  
    39. {  
    40.     CircleCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Circle_Cell" forIndexPath:indexPath];  
    41.     return cell;  
    42. }  
    43.   
    44. //手势的相应事件  
    45. - (void)handleTapGesture:(UITapGestureRecognizer *)sender {  
    46.       
    47.     if (sender.state == UIGestureRecognizerStateEnded)  
    48.     {  
    49.         CGPoint initialPinchPoint = [sender locationInView:self.collectionView];  
    50.         NSIndexPath* tappedCellPath = [self.collectionView indexPathForItemAtPoint:initialPinchPoint];  
    51.         if (tappedCellPath!=nil)  
    52.         {  
    53.             self.cellCount = self.cellCount - 1;  
    54.             [self.collectionView performBatchUpdates:^{  
    55.                 [self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:tappedCellPath]];  
    56.                   
    57.             } completion:nil];  
    58.         }  
    59.         else  
    60.         {  
    61.             self.cellCount = self.cellCount + 1;  
    62.             [self.collectionView performBatchUpdates:^{  
    63.                 [self.collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:0 inSection:0]]];  
    64.             } completion:nil];  
    65.         }  
    66.     }  
    67. }  
    68. - (void)didReceiveMemoryWarning  
    69. {  
    70.     [super didReceiveMemoryWarning];  
    71.     // Dispose of any resources that can be recreated.  
    72. }  
    73.   
    74. @end  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值