在使用uicollectionview用法碰到的诡异问题,求解答

iOS6新特征:UICollectionView官方使用示例代码研究
注:这里是iOS6新特征汇总贴链接&&&
这个链接可以学习到UICollectionView的相关介绍:&
由于UICollectionView功能比较强大,在此,我们深入学习一下UICollectionView的官方使用示例代码,顺与大家分享一下心得。&
一、获取官方示例代码
:如下图所示
下载后,解压将CollectionView目录拖放进一个目录下(如你的文稿目录)
二、加载示例代码
启动Xcode 这里我用的是Xcode
4.5(4G182)版本。选择“Open
Other…”打开CollectionView工程项目。
项目打开并加载后象是这样的,如图:
从工程项目属性中可看出,官方原代码设计已经同时支持Retina
3.5-inch(640*960)屏和Retina
4-inch(640*1136pixels)屏,如图:
官方原代码设计还支持Retina Display 2048*1096高清设计,只可惜本人电脑是黑苹果,电脑硬件不支持!所以显示“!”号,等发同发财了购买一台白苹果再试试。
三、运行效果
下面先看看官方原代码的实际运行的效果图,使用iPhone6.0模拟器测试运行程序,刚刚启动时,已经默认加载了6个cell。通过这样的一个Demo,我们可以看出,使用UICollectionView可以很方便的制作出照片浏览等应用。
点击其中任一张图片,导航进入下一祥细视图:
四、Collection
View的整体构成元素
我们先来感性的认识一下CollectionView工程项目,下面这幅图就是用CollectionView实现的一个照片墙显示的工程项目文件结构。
我们知道:Collection View的整体构成元素,共有三个要素,分别如下
Cells(单元格)
Supplementary Views(补充的view,相当于TableView的页眉和页脚)
Decoration
Views(装饰View,用于装饰整个Collection
我们可以分解一下这个项目结构,来描述上面的三个元素都对应什么内容
1、缺省图片文件5个,分别以Default开头,用来支持各种设备屏幕,如下图:
2、资源图片共32张,其中大图片命名为0_full.jpg—31_full.jpg,小图片命名为0.jpg—31.jpg,用来供显示的数据图片。这里我们可以要注意一下它的命名,主要是为了方便下面的程序设计。如图:
五、关键文件代码
关键文件代码的目录如下图所示:
从上图,可以看到这个Demo有10个关键文件,下面分别对其进行介绍。
1、主函(main.m)代码
首先看一下主函数代码:没有什么特别的,与以前的完全一样一样的。
#import "AppDelegate.h"
int main(int argc, char *argv[])
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
如下图,由三个视图控制器组成,分别是导航控制器、主视图控制器和祥细页控制器,下面还要具体讲!
3、代理类AppDelegate.h/.m代码介绍
AppDelegate.h头文件更简单,只有三行代码,完全自动长成的。
@interface AppDelegate : UIResponder &&/SPAN&UIApplicationDelegate&
这里要说明的是,它继承的是UIResponder类。
在AppDelegate.m实现文件也简单,6个函数也完全自动长成的,不需要用户输入代码。
这里要提一下:以前在方法didFinishLaunchingWithOptions中,通常要创建一个rootViewController控制器等,现在完全省略了,直接返回Yes。如图:
4、主控制器(ViewController.h/m)类介绍
ViewController.h
@interface ViewController : UICollectionViewController
ViewController是继承自UICollectionViewController,它负责显示Collection View的所有内容。
ViewController.m类
通常在这里实现Collection View的dataSource和delegate。下面的代码实现了如下两个方法:
(NSInteger)collectionView:(UICollectionView *)view
numberOfItemsInSection:(NSInteger)
(UICollectionViewCell *)collectionView:(UICollectionView *)cv
cellForItemAtIndexPath:(NSIndexPath *)indexP
我们先看看它的设计视图,在主控制器中包括一个Cell,一个Libel,一个UIImage
View。如下图,
这里我们要重点关注一下它的布局结构。
我们知道:UICollectionViewLayout类是一个抽象基类,通过继承它以生成collection view的layout信息。layout对象的职责就是决定collection view中cells,supplementary
views和decoration
views的位置,当collection
view请求这些信息时,layout对象会提供给collection view。collection
view就使用laout对象提供的信息把相关的view显示在屏幕上。
注意:要使用UICollectionViewLayout必须先子类化它。同时子类化时还需要注意的是:layout对象不负责创建views,它只提供layout(布局),view的创建是在collection view的data
source中。layout对象定义了view的位置和size等布局属性。
看看上面一大堆知识,说不难都不相信,但苹果在推出Xcode 4.5时,在这方面做了大大的改进,使用自动布局中的Constraints!如下图:
下面是ViewController.m的原代码,由于有上面的介绍,不祥述了,重点地方看看注释,英文注释是官方解释的。&
#import "ViewController.h"
#import "DetailViewController.h"
#import "Cell.h"&
NSString *kDetailedViewControllerID = @"DetailView";&&&
// view controller storyboard id
NSString *kCellID = @"cellID";&&&&&&&
// UICollectionViewCell storyboard
@implementation ViewController&
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)
return 32; //返回32张图片
//这个函数很关键,不懂怎么用可查查资料!
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexP
// we're going to use a custom UICollectionViewCell,
which will hold an image and its label
Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
// make the cell's title the actual NSIndexPath
cell.label.text = [NSString stringWithFormat:@"{%ld,%ld}", (long)indexPath.row, (long)indexPath.section];
// load the image for this cell
NSString *imageToLoad = [NSString stringWithFormat:@"%d.JPG", indexPath.row];
cell.image.image = [UIImage imageNamed:imageToLoad];
// the user tapped a collection item, load and set the
image on the detail view controller
//这个函数是向下一个视图控制器传送的数据!
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDetail"])
&&&&&NSIndexPath *selectedIndexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
// load the image, to prevent it from being cached we
use 'initWithContentsOfFile'
NSString *imageNameToLoad = [NSString stringWithFormat:@"%d_full", selectedIndexPath.row];
NSString *pathToImage = [[NSBundle mainBundle] pathForResource:imageNameToLoad ofType:@"JPG"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathToImage];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.image =
5、Cell.h/m介绍
在此自定义了一个简单的cell:继承自UICollectionViewCell。
UICollectionViewCell : UICollectionReusableView : UIView
当item在collection
view的可视范围内时,UICollectionViewCell负责显示单个item数据的内容,你可以通过as-is关系来使用它,当然,也可以继承(subclass)自它,以添加一些额外的属性和方法。cell的layout和显示是有collection view管理的,并且cell与layout对象相互对应。
正如前面介绍,这里由于使用了自动布局,cell与layout对象相互对应在故事板中实现,因此,在这里,使用继承(subclass)机制,来给cell添加了一个UIImageView,用来显示一副图片,一个UILabel,用来显示一个标签。代码很简单,看下面的具体实现即可。在.m文件里面使用了一个CustomCellBackground类,来实现对Cell进行了画背景类填充颜色处理。
@interface Cell : UICollectionViewCell
@property (strong, nonatomic) IBOutlet UIImageView *
@property (strong, nonatomic) IBOutlet UILabel *
#import "Cell.h"
#import "CustomCellBackground.h"
@implementation Cell
- (id)initWithCoder:(NSCoder *)aDecoder
self = [super initWithCoder:aDecoder];
&// change to our custom selected background
CustomCellBackground *backgroundView = [[CustomCellBackground alloc] initWithFrame:CGRectZero];
self.selectedBackgroundView = backgroundV
return self;
画背景类填充颜色
CustomCellBackground.h
@interface CustomCellBackground : UIView
CustomCellBackground.m
#import "CustomCellBackground.h"
@implementation CustomCellBackground
- (void)drawRect:(CGRect)rect
// draw a rounded rect bezier path filled with
CGContextRef aRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(aRef);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:5.0f];
[bezierPath setLineWidth:5.0f];
[[UIColor blackColor] setStroke];
UIColor *fillColor = [UIColor colorWithRed:0.529 green:0.808 blue:0.922 alpha:1]; // color equivalent is #87ceeb
[fillColor setFill];
[bezierPath stroke];
[bezierPath fill];
CGContextRestoreGState(aRef);
6、祥细视图控制器类DetailViewController.h/m
这个页面设计非常简单,只有一个UIViewController,上面加了一个UIImage控件,用来显示从前一页面传送过来的图片!
DetailViewController.h
@interface DetailViewController : UIViewController
@property (nonatomic, strong) UIImage *
DetailViewController.m
#import "DetailViewController.h"
@interface DetailViewController ()
@property (nonatomic, weak) IBOutlet UIImageView *imageV
@implementation DetailViewController
- (void)viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
self.imageView.image = self.image;
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。他山知识网
IT专业问题解答
reloadItemsAtIndexPaths后避免UICollectionView动画
UICollectionView reloadItemsAtIndexPaths后动画项目被称为(渐变动画).有没有办法来避免这种动画?的iOS 6
Rank -- &nbsp4
你也可以试试这个:
UICollectionView *collectionV
[UIView setAnimationsEnabled:NO];
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];} completion:^(BOOL finished) {
[UIView setAnimationsEnabled:YES];}];
编辑:我还发现,如果你包
performBatchUpdates
在一个UIView动画块,UIView的动画来代替默认的动画,所以你可以设置动画持续时间为0,如下所示:
[UIView animateWithDuration:0 animations:^{
[collectionView performBatchUpdates:^{
[collectionView reloadItemsAtIndexPaths:indexPaths];
} completion:nil];}];
这是额外的冷静,如果你想插入过程中使用的iOS 7弹性的动画和删除!
Rank -- &nbsp1
我写了一个
做到这一点.关键是要停用所有的动画,而重装:
if (!animated) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];}
[self reloadItemsAtIndexPaths:indexPaths];
if (!animated) {
[CATransaction commit];}
Rank -- &nbsp0
- (void)reloadCollectionViewAnimated:(BOOL)animated
if (animated) {
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
[CATransaction commit];
2013 - 2014 版权所有iOS 问题:UICollectionView设置完后不触发didSelectItemAtIndexPath,代理啥的都设置了,就是不走这个方法。
UICollectionView设置完后不触发didSelectItemAtIndexPath,代理啥的都设置了,就是不走这个方法。
共有 1 个回答
粘贴一下你的源代码呀,不然怎么知道问题出现在什么地方
登录后方可回复
登录后方可回答
耗时 0.0688 秒1761人阅读
CircleLayout继承自UICollectionViewLayout,在这里先简单介绍一下UICollectionViewLayout
UICollectionViewLayout类是一个抽象基类,通过继承它以生成collection view的layout信息。layout对象的职责就是决定collection
view中cells,supplementary views和decoration views的位置,当collection
view请求这些信息时,layout对象会提供给collection view。collection
view就使用laout对象提供的信息把相关的view显示在屏幕上。
注意:要使用UICollectionViewLayout必须先子类化它
子类化时需要注意的事项:
layout对象不负责创建views,它只提供layout(布局),view的创建是在collection
view的data source中。layout对象定义了view的位置和size等布局属性。
collection view有三种可视元素需要layout:
Cells:cells是layout管理的主要元素。每一个cell代表了collection
view中的单个数据item。一个collection view可以把cell放到一个section中,也可以把cell分为多个section。layout的主要职责就是组织collection
view的cells。
Supplementary views:supplementary view也显示数据,但是与cells不同。并不像cell,supplementary
view不可以被用户选择。相反,可以使用supplementary view来给一个section实现类似页眉和页脚,当然不仅仅是section,也可以是整个collection
view。supplementary view是可选的,并且他们的使用和位置是由layout对象定义的。
Decoration views:decoration view是用于装饰的,不可以被用户选择,并且它的相关数据没有与collection
view绑定。decoration view是另外一种supplementary view。类似supplementary
view,decoration view也是可选的,,并且他们的使用和位置是由layout对象定义的。
collection view会在许多不同时间里面,请求这些元素的layout对象以获得相关&layout信息。每一个出现在屏幕中的cell和view的位置是有layout对象提供的。类似的,每次从collection
view中插入或者删除item,相应的layout也会被添加或者移除。当然,collection
view总是会限制layout对象数目:即只针对屏幕的可视范围。
需要重载的方法
每个layout对象都需要实现下面的方法:
collectionViewContentSize
shouldInvalidateLayoutForBoundsChange:
layoutAttributesForElementsInRect:
layoutAttributesForItemAtIndexPath:
layoutAttributesForSupplementaryViewOfKind:atIndexPath: (如果layout&支持&supplementary
layoutAttributesForDecorationViewWithReuseIdentifier:atIndexPath: (如果layout&支持&decoration
这些方法具体作用,可以查阅相关的sdk即可知晓。
当collection view中的数据发生了改变,如插入或删除item,那么collection
view会请求这些item的layout对象,以更新layout信息。特别是,任意的item被移动,添加或者删除了,必须要有它相关的layout信息来更新相关的新位置。对于移动一个items,collection
view会使用标准的方法来检索item的layout属性。对于item的插入和删除,collection
view会调用一些不同的方法,你应该重载这些方法,以提供相关的layout信息:
initialLayoutAttributesForInsertedItemAtIndexPath:
initialLayoutAttributesForInsertedSupplementaryElementOfKind:atIndexPath:
finalLayoutAttributesForDeletedItemAtIndexPath:
finalLayoutAttributesForDeletedSupplementaryElementOfKind:atIndexPath:
下面的代码中就是使用到了item的插入和删除。所以重载了下面两个方法:
initialLayoutAttributesForInsertedItemAtIndexPath:
finalLayoutAttributesForDeletedItemAtIndexPath:
对于layout在collection view中的作用非常重大,你的画面显示什么效果就看你如何定义layout了。更多相关信息还请阅读相关sdk中的内容。在此不再进行详细的讲解。
//&&CircleLayout.h
//&&DevDiv_CollectionView_CircleLayout_Demo
//&&Created by BeyondVincent on 12-7-3.
//&&Copyright (c) 2012年&DevDiv.
All rights reserved.
@interface&CircleLayout :&UICollectionViewLayout
@property&(nonatomic,&assign)&CGPoint&
@property&(nonatomic,&assign)&CGFloat&
@property&(nonatomic,&assign)&NSInteger&cellC
//&&CircleLayout.m
//&&DevDiv_CollectionView_CircleLayout_Demo
//&&Created by BeyondVincent on 12-7-3.
//&&Copyright (c) 2012年&DevDiv.
All rights reserved.
#import&&CircleLayout.h&
#define ITEM_SIZE&70
@implementation&CircleLayout
-(void)prepareLayout
&&&&[super&prepareLayout];
&&&&CGSize&size
=&self.collectionView.frame.size;
&&&&_cellCount&=
[[self&collectionView]&numberOfItemsInSection:0];
&&&&_center&=&CGPointMake(size.width&/&2.0,
size.height&/&2.0);
&&&&_radius&=&MIN(size.width,
size.height) /&2.5;
-(CGSize)collectionViewContentSize
&&&&return&[self&collectionView].frame.size;
- (UICollectionViewLayoutAttributes&*)layoutAttributesForItemAtIndexPath:(NSIndexPath&*)path
&&&&UICollectionViewLayoutAttributes*
attributes&= [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:path];
&&&&attributes.size&=&CGSizeMake(ITEM_SIZE,&ITEM_SIZE);
&&&&attributes.center&=&CGPointMake(_center.x&+&_radius&*&cosf(2&*
path.item&*&M_PI&/_cellCount),
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_center.y&+&_radius&*&sinf(2&*
path.item&*&M_PI&/_cellCount));
&&&&return&
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
&&&&NSMutableArray*
attributes = [NSMutableArray&array];
&&&&for&(NSInteger&i=0&;
i &&self.cellCount;
i++) {
&&&&&&&&NSIndexPath*
indexPath = [NSIndexPath&indexPathForItem:i&inSection:0];
&&&&&&&&[attributes&addObject:[self&layoutAttributesForItemAtIndexPath:indexPath]];
&&&&return&
- (UICollectionViewLayoutAttributes&*)initialLayoutAttributesForInsertedItemAtIndexPath:(NSIndexPath&*)itemIndexPath
&&&&UICollectionViewLayoutAttributes*
attributes&= [self&layoutAttributesForItemAtIndexPath:itemIndexPath];
&&&&attributes.alpha&=&0.0;
&&&&attributes.center&=&CGPointMake(_center.x,&_center.y);
&&&&return&
- (UICollectionViewLayoutAttributes&*)finalLayoutAttributesForDeletedItemAtIndexPath:(NSIndexPath&*)itemIndexPath
&&&&UICollectionViewLayoutAttributes*
attributes = [self&layoutAttributesForItemAtIndexPath:itemIndexPath];
&&&&attributes.alpha&=&0.0;
&&&&attributes.center&=&CGPointMake(_center.x,&_center.y);
&&&&attributes.transform3D&=&CATransform3DMakeScale(0.1,&0.1,&1.0);
&&&&return&
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:193286次
积分:4126
积分:4126
排名:第2681名
原创:154篇
转载:421篇
评论:19条
(9)(31)(26)(13)(13)(38)(37)(4)(6)(27)(14)(17)(40)(48)(35)(11)(2)(34)(57)(13)(24)(60)(19)}

我要回帖

更多关于 uicollectionview 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信