iOS6开发----应用集合视图(UICollectionView)-添加单元格详细视图
关于集合视图UICollectionView的相关文章:
第三十一部分:应用集合视图(UICollectionView)-使用xib文件创建集合视图单元格 第三十一部分:应用集合视图(UICollectionView)-创建UICollectionViewCell子类单元格 第三十一部分:应用集合视图(UICollectionView)-创建基于Storyboard的集合视图应用程序 第三十一部分:应用集合视图(UICollectionView)-实现补充视图(Supplementary View) 第三十一部分:应用集合视图(UICollectionView)-删除集合视图数据项
本文摘录自《一步一步学习 iOS 6 编程(第四版)》电子书,部分截图省略。
添加单元格详细视图
下面考虑进一步给集合视图中的单元格添加详细视图,也就是选择任一单元格,将导航到相应的详细视图,显示更大的图像。
本章最后完成之后的App运行效果如下图所示:
首先,打开Storyboard,选择唯一的一个场景。然后选择Editor > Embed In > Navigation Controller 菜单项,在项目中添加导航控制器。
选择集合视图场景中的导航标题栏,设置导航标题为爱车图库。
然后,在Storyboard中添加一个新的场景,用来显示图像详细视图。从对象库拖拉一个View Controller 对象到Storyboard画布中,就自动创建一个新的空白场景。 接着,选择文档大纲面板中的Photo Collection View Cell对象,拖拉到新的场景中,在弹出菜单中,选择Push 选项。这样,在选择集合视图中的任一单元格,将会切换到新的详细视图场景中。
选择创建的联线(Segue),在Attributes inspector面板窗口,设置Identifier(标识符)属性为showDetail,这个标识符在后面的代码编写中会用到。
下一步,在新的创建中添加一个图像视图(UIImageView),图像视图覆盖整个场景大小,用来显示更大的图像。同时,在Attributes inspector面板窗口,设置图像视图的Mode属性为Aspect Fit。
下面,创建详细视图场景对应的视图控制器类PhotoDetailViewController。 在项目中新增文件,选择iOS Cocoa Touch节点中的Objective-C Class模板。在接下来的窗口中,设置类名为PhotoDetailViewController,Subclass of 下拉框中选择UIViewController。操作完成之后,在项目中自动添加PhotoDetailViewController类的头文件和实现文件。
在Storyboard画布中,选择详细视图场景,然后在Identity inspector面板窗口,设置Class属性为刚刚创建的PhotoDetailViewController类。操作完成之后,整个Storyboard画布将如下图所示:
准备工作基本完成了。接下来开始详细视图的编码工作了。
当然,还需要建立图像视图到视图控制器的输出口连接,输出口命名为imageView。另外,我们还需要在PhotoDetailViewController.h中定义一个属性(property),命名为image。初始场景将在prepareForSegue:方法中访问这个属性,给其传递信息。
完成上述操作之后,PhotoDetailViewController.h文件的代码如下所示: #import <UIKit/UIKit.h> @interface PhotoDetailViewController : UIViewController @property (strong, nonatomic) IBOutlet UIImageView *imageView; @property (strong, nonatomic) UIImage *image; @end
现在回到Storyboard画布中,因为初始场景中已经有导航栏了,因此集合视图的标题可以考虑取消掉。选择初始场景中的集合视图对象,然后在Attributes inspector 面板窗口中,取消Section Header的选择。
当然,还需要在PhotoCollectionViewController.m文件中,注释掉之前实现的两个方法,分别用来(1) 设置集合视图的标题;(2) 在选择集合视图单元格时,删除所选择的单元格。现在这两个方法没有用途了。 /* - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ PhotoSupplementaryView *header = nil; if([kind isEqual:UICollectionElementKindSectionHeader]){ header = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"PhotoHeader" forIndexPath:indexPath]; header.headerLabel.text = @"爱车和美女"; } return header; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ int row = [indexPath row]; [self.photoImages removeObjectAtIndex:row]; NSArray *deleteItems = @[indexPath]; [self.collectionView deleteItemsAtIndexPaths:deleteItems]; }*/
因为PhotoCollectionViewController.m文件需要访问详细视图中的属性,在切换视图时,传递数据,因此在PhotoCollectionViewController.m文件头部添加对PhotoDetailViewController.h头文件的引入。 #import "PhotoDetailViewController.h"
下一步,在PhotoCollectionViewController.m文件中添加prepareForSegue:方法的实现。 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([[segue identifier] isEqualToString:@"showDetail"]){ NSIndexPath *selectedIndexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
PhotoDetailViewController *detailViewController = [segue destinationViewController]; detailViewController.image = [UIImage imageNamed:self.photoImages[selectedIndexPath.row]]; } }
获取所选集合视图单元格NSIndexPath对象,然后根据该对象的row属性,获得image对象,最后赋值给详细视图的image属性,在视图切换过程中进行数据传递。 现在打开PhotoDetailViewController.m文件,编写viewWillAppear:方法,在场景的图像视图中加载所选择的图像。 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.imageView.image = self.image; }
好啦!代码编写好了。我们现在运行应用程序,看看运行效果是否符合预期。
选择第一个单元格,切换到详细视图场景,显示更大的图像。 选择模拟器的硬件 > 向右旋转菜单项,应用程序及其视图布局仍然符合我们的要求。