【无限互联】IOS开发之瀑布流的实现(UICollectionView与UIScrollView)_第1页
【无限互联】IOS开发之瀑布流的实现(UICollectionView与UIScrollView)_第2页
【无限互联】IOS开发之瀑布流的实现(UICollectionView与UIScrollView)_第3页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、if (group) groupenumerateAssetsUsingBlock:a( ALAsset *result, NSUlnteger index, BOOLBOOLstop) if(result) ALAssetRepresentation*resentation = resultdefaultReprlibraryenumerateGroupsWithTypes :ALAssetsGroupSavedPhotos usingBlock:A(ALAssetsGroup *group, BOOLBOOLstop) esentation ;CGlmageRef imageRef = r

2、esentation.fullResolutionlmage;Ullmage *image = Ullmage imageWithCGlmage :imageRef;【无限互联】IOS开发之瀑布流的实现(UlCollectionView 与UlScrollView)瀑布流可以在保证图片原始比例的情况下,灵活的展现内容,相对于传统的使用相同大小的网格展现大量图片,要好上很多,而实现瀑布流的方式有很多种,网上比拟流行的有三种实 现方式。1,使用UlScrollView,主要技术点在于视图的重用。2,使用UlTableView,这种方式应该是最易想到的,因为需要展现几列就用几个tabelview就o

3、k 了,而且不需要考虑重用,应为苹果已经做好了,只需要考虑如何在几列tabelView滑动的时候,保持同步不出现 BUG。3,使用 UlCollectionView , UlCollectionView在 iOS6 中第一次被介绍,它与 UlTableView有许多相似点,但它多了一个布局类,而实现瀑布流,就与这个布局类有关。此种方式实现, 也不需要考虑视图重用。以上三种方式实现瀑布流,使用UlCollectionView应该算是最简单的了 ,so,就重最简单的开始吧。由于网络太差,所以展现的并不是网络上的图片,而是将用户相册中的图片读取出,并用瀑布流展现。首先,遍历用户相册,将照片放到准备好

4、的数组中。访问用户相册需要导入框架<AssetsLibrary/AssetsLibrary.h>objc view pla in copy..2.<span style= "font-size:14px;" > _images = NSMutableArrayarray ;/创立相册库library = ALAssetsLibraryalloc init ;2.23.24./将相片参加到数组中self .images addObject :image

5、;_collectionViewreloadData ;; failureBlock:A( NSError *error) ;v/span>然后创立UlCollectionView ,注意这里放置 UlCollectionView 的控制器要实现,UICollectionViewDelegateFlowLayout和 UlCollectionViewDatasource 两个协议。UICollecti on View创立时需要传入一个布局对象,布局类继承自UlCollectionViewLayout这个抽象基类,我们需要自定义布局对象,继承UlCollectio nV iewLayout

6、的子类,UlCollectio nViewFlowLayout类,命名为WaterFlowLayout 。objc view pla in copy1.vspan style="font-size:14px;">interface WaterFlowLayout : UlCollectionViewFlowLperty (nonatomic ,assign)id <UICollectionViewDelegateFlowLayout> delegate;3.4.end5.</span>1objcview pla in cop

7、y1.vspan style="font-size:14px;">WaterFlowLayout *layout = WaterFlowLayout alloc init ;2.3._collectionView = UlCollectionViewalloc initWithFrame:UlScreenmainScreen .bounds collectionViewLayout :layout;.9.10._collectionView.dataSource =self ;_collectionView.delegate =self ; self .

8、view addSubview :_collectionView;/注册单元格_collectionViewregisterClass:WaterfallCellclass forCellWithReuseldentifier:indf;11.v/span>设置好代理,下面实现代理协议就行了,在这里同样子类化了UlCollectio nV iewCell,命名为WaterfallCell,并设置一个image属性,便于在协议方法中将照片传入。objcview pla in copy1.vspan style= "font-size:14px;">interfac

9、e WaterfallCell : UlCollectionViewCperty ( nonatomic , retain ) Ullmage *image; enc</span>实现 UlCollectionViewDatasource协议。objcview pla in copy1.vspan style= "font-size:14px;">- (NSlnteger)collectionView:(UlCollectionView*)collectionView numberOfltemsInSection :(NSInteger)

10、section.return _images.count;/ The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseldentifier:forlndexPath:6.-(UlCollectionViewCell*)collectionView:(UlCollectionView*)collectionViewcellForltemAtlndexPath :( NSIndexPath *)indexPath7.WaterfallCell*cell = coll

11、ectionViewdequeueReusableCellWithReuseldentifier:indf forlndexPath:indexPath;4.Ullmage *image = _imagesindexPath.item; cell.image = image;return cell;</span>实现 UlCollectionViewDelegateFlowLayout协议,将单元格的尺寸传入, 这里让每张图片的宽度保持相同,高度等比例缩放。objc view pla in copy1.<span style= "f

12、ont-size:14px;">-(CGSize)collectionView:(ollectionView layout :(UICollectionViewLayout*)collectionViewLayoutUICollectionView *)csizeForltemAtlnd2.3.exPath :( NSIndexPath *)indexPath UIImage *image = _imagesindexPath.item;4.5.6.float height = self imgHeight:image.size.heightWidth :image.size.

13、width7.8.return CGSizeMake(100,height);9.10.11./单元格中的间隙12.-(UIEdgeInsets)collectionView:(UICollectionView*)collectionViewlayoutCollectionViewLayout*)collectionViewLayoutinsetForSectionAtIndex:(NSInteger)section13.UIEdgeInsets edgeInsets = 5,5,5,5;14.15.return edgeInsets;16.17.-(float )imgHeight:( fl

14、oat )heightWidth :( float )width18.19./单元格固定宽度为100高度/宽度=压缩后高/10020.float newHeigth = height/width*100;21.return newHeigth;22.23.v/span>:(UI以上完成以后,控制器中的逻辑根本处理完毕,下面重写cell的setter方法,简单起见,我并没有创立Imageview显示图片,而是将图片直接绘制在了单元格上。| objcview pla in copy1. - ( void )setImage:( UIImage *)image2. if (_image !=

15、image) 3. m age = image;.7.18.I..5. self setNeedsDisplay ;/ Only override drawRect: if you perform custom drawing./ An empty implementation adversely affects performance during animation.-(void )drawRect:(CGRect)rect/ Drawing codefloat

16、 newHeigth =m age.size.height/_image.size.width*100;_image drawInRect :CGRectMake(O, 0, 100, newHeigth);cell处理完毕后,下面就是最重要的布局类了,瀑布流就是依靠此类来展现的首先在-(void)prepareLayout 方法中得到cell的总个数,为每个cell确定自己的位置,此处用三列展现图片,当然列数可以随意设置,这取决与图片的宽度。在layoutForltemAtlndexPath方法中为每个 cell做布局,首先创立一个数组,存储三列的高度,每次遍历数组,找出最短列,将cell插

17、入到最短列,而cell的高度和宽度,可以通过调用前面视图控制器实现的代理协议得到。objc view pla in copy/准备布局-(void )prepareLayout super prepareLayout ;attributesDic = NSMutableDictionarydictionary ;self .delegate = ( id <UICollectionViewDelegateFlowLayout>)self .collectionView.delegate;/获取cell的总个数numberOfltemsInSection :0;cellCount =

18、 self .collectionViewif (cellCount = 0) return ;array ; /列数 此处为3列 数组中存储每列的高度colArr = NSMutableArrayfloat top = 0;16.17.for ( int i = 0; i < 3; i+) colArraddObject :NSNumber numberWithFloat:top;1./ 循环调用 layoutAttributesForltemAtlndexPath indexPath传入,做为布局字典的 key方法为每个cell计算布局,将22.for ( int

19、 i =0; i < cellCount; i+) 23.self layoutForltemAtlndexPath:NSIndexPathindexPathForltem :i inSection:0;7.objcview pla in copy1.b(255, 255, 255);"<span style= "font-family: Arial, Helvetica, sans-serif; background-color: rg>下面是v/span><span style= "font-family: A

20、rial, Helvetica, sans-serif; font-size: 14px; bac>layoutForltemAtlndexPath方法的实现,这里用到了一个..kground-color: rgb(255, 255, 255);"布局字典,其实就是将每个cell的位置信息与indexPath相对应,将它们存入字典中,之所以用到这个字典,是为了后面视图的检索。</span>objc view pla in copy/此方法会屡次调用为每个cell布局-(void )layoutForltemAtlndexPath:(/调用

21、协议方法得到cell间的间隙UlEdgelnsets edgelnsets =View layout : self insetForSectionAtlndexedge = edgelnsets;CGSize itemSize =selfut: selfsizeForltemAtlndexPathNSIndexPath *)indexPathself .delegate collectionView : self .collection:indexPath.row;.delegate collectionView:self .collectionViewlayo:indexPath;9.10.

22、NSlnteger col = 0;/ 列数11.12./找岀高度最小列,将 cell加到最小列中13.float shortHeigth = colArrobjectAtlndex:colfloatValue14.for ( int i = 1; i< colArr.count; i+) 15.float colHeight = colArrobjectAtlndex:ifloatValue;16. if (colHeight < shortHeigth) 17. shortHeigth = colHeight;18. col = i;19. 20. 21. float top

23、= colArrobjectAtlndex :col floatValue ;22.22. /确定每个cell 的frame23. CGRect frame = CGRectMake(edgelnsets.left + col*(edgelnsets.left+itemSize.width), top+edgelnsets.top, itemSize.width, itemSize.height);25.26. /cell 参加后,更新列高27. colArr replaceObjectAtIndex :col withObject :NSNumber numberWithFloat:top

24、+ edgelnsets.top+itemSize.height;28.29./每个cell的frame 对应一个indexPath, 存入字典中30.attributesDicsetObject :indexPath forKey :NSStringFromCGRect(frame);31.32.为每个cell布局完毕后,还需要实现一个很重要的方法,-(NSArray *)layoutAttributesForEleme ntsl nRect:(CGRect)rect此方法会传入一个 UICollectionView当前可见的frame ,需要返回需要显示的 cell信息,数组中需要装入UI

25、Collectio nV iewLayoutAttributes类创立的对象。UICollectionViewLayoutAttributes类包含了 collection view 内 item 的所有相关布局属性。默认情况下,这个类包含 frame ,center ,size, transform3D , alpha 等信息, 其实就是对每个cell位置信息的抽象。当然你可以忽略传入的rect简单粗暴的将所有 cell的布局信息放入数组中全部返回,我看了网上很多代码也都是这样做的,这样做是可以实现效果了,按cocoa上的一篇关于UICollectionView译文的说法,此种做法是一种很幼

26、稚的实现。因为当可见的cell远少于不可见cell的数量时,性能可能会灰常差,ok,为了使实现不那么幼稚,前面的布局字典就用到了。遍历布局字典,将每个cell的frame 与系统传入的frame 使用CGRectlntersectsRect方法,判断字典中的那些cell的frame 与传入的frame 有交集如果结果为true说明此..2.13.14.I..5.cell需要显示,那么就将cell对应的indexPath放入准备好的数组中,之所以需要indexPath ,是因为 UlCo

27、llectionViewLayoutAttributes类需要 indexPath来实例化,以此来对应每个 cell。objc view pla in copy-(NSArray *)indexPathsOfltemslnRect:(CGRect)rect/遍历布局字典通过 CGRectIntersectsRect方法确定每个cell的rect 与传入的rect是否有交集,如果结果为true,那么此cell应该显示,将布局字典中对应的indexPath 参加数组NSMutableArray *indexPaths = NSMutableArrayarray ;for ( NSString *r

28、ectStr in attributesDic) CGRect cellRect = CGRectFromString(rectStr);if (CGRectIntersectsRect(rect, cellRect) NSIndexPath *indexPath = attributesDicrectStr;indexPathsaddObject :indexPath;return indexPaths;objc view pla in copy/此方法会传入一个collectionView 当前可见的rect,视图滑动时调用/需要返回每个cell的布局信息,如果忽略传入的rect 一次性将所有的cell布局信息返回,图片过多时性能会很差-(NSArray *)layoutAttributesForElementslnRect:(CGRect)rectarray ;NSMutableArray *attributes = NSMutableArray

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论