在前面我们已经学过了UICollectionView的基本的东西。如果你没有看过你可以去看看前面的写的文章。
正如前面提到的那样,Collection view和UITableView很相似,但我们将给你一个更好的方法去展示集合项目,例如处理单个或者多个项目进行交互。我们会继续使用前面的代码继续改进来完成下面的的要求:
为了演示如何处理单个的选择,我们将改进应用程序,当用户点击一个照片,这个应用程序就会跳出一个魔胎试图,并且能够以较大的尺寸显示照片。
我们可以实现分享
如下图显示:
这个应用程序很简单,不会给你带来任何设计奖项,但是它却可以给你提供了一个比较好的交互想法,如果你没有看过前面写的blog你可以选择在download this Xcode template这里下载。但是至少要在xcode4.6或以后的版本编辑才好。
处理单个的选择
首先,我们要改变应用程序来处理这个选择:当用户点击任一图片,这个应用都会弹出一个模态视图,以显示更加高画质的图片。
设计用户界面
首先,让我们来设计视图控制器来显示照片。到 stroyboard,从对象库中拖动一个ImageView到view controller,并分别设置高度为200和宽度为320。最后,添加一个导航栏到视图的顶部,并添加一个bar button item,并命名为"Colse",就像下面显示的:
因为我们希望当用户点在collection view中击任何图片的时候,都要在视图控制器中显示,所以我们使用联线来链接collection view和view controller。按下Ctrl键,然后点击"Recipe View Cell“然后拖向视图控制器,选择"modal"风格,设置segue identifier为“showRecipePhoto”。
如果你现在运行你的应用程序,你你点击图片会跳转到一个空白界面,这是为啥勒,因为我们没有用代码去实现,模态视图不知道啥图片要显示,啥不显示所以不显示咯。所以我们要创建一个新的类(也是继承自UIViewController),命名为"RecipeViewController ",回到storyboard,选择刚刚创建的视图控制器并设置custom class为RecipeViewController,如图:
下一步,我们将刚刚建立的视图和RecipeViewController 链接,按住Ctrl键,点击image view并向RecipeViewController.h拖动。变量名为"recipeImageView"重复上面的步骤,并链接“close”到recipeViewController.h选择"action"。
添加代码
为了让其他控制器得到image name,我们也将添加一个"recipeImageName"属性,下面是RecipeViewController.h中的片段
@interface RecipeViewController:UIViewController
@property (weak,nonatomic)IBOutlet UIImageView *recipeImageView;
@property (weak,nonatomic)NSString *recipeImageName;
- (IBAction)close:(id)sender;
当显示的时候,RecipeViewController会加载指定的图像,所以我们在RecipeViewController.m中的viewDidLoad方法中添加下面的代码:
- (void)viewDidLoad
{
[super viewDidLoad];
self.recipeImageView.image = [UIImage imageNamed:self.recipeImageName];
}
好了,到这里我们已经实现了RecipeViewController,但是仍有一件事情,我们怎样才能把UICollectionView中的指定项目的图像的名称传递给RecipeViewController?我们要实现在RecipeCollectionViewController中的prepareForSegue:sender:方法。这是segue的source视图控制器,选择"RecipeBookViewController.m"添加下面的代码:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showRecipePhoto"]){
NSArray *indexPaths = [self.collectionView indexPathsForSelectedItems];
RecipeViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [indexPath objectAtIndex:0];
destViewController.recipeImageName = [recipeImages[indexPath.sectioln] objectAtIndex:indexPath.row];
[self.collectionView deselectItemAtIndexPath:indexPath animated:NO];
}
}
注意:如果不知道segue怎样使用你可以看这里our segue tutorial
UICollectionView提供了indexPathsForSelectedItems方法,返回所选项目的index path。也许你想知道为什么有多个index path返回,原因是,UICollectionView支持多选,我们将在下一节讨论这个,至于现在的例子,我们只选择一个项目,因此,我们选择第一个索引的路径和检索所选的(NSIndexPath这一行到destViewController这行)。
在UICollectionView中,当用户点击一个collection cell,cell变成高亮的状态。因此,一旦我们选择图像在模态视图控制器 控制器中显示,那么我们就要添加一点代码来取消选择项目。
不要忘记在RecipeCollectionViewController.m开始的时候添加import语句,否则,你的代码将不能编译:
#import "RecipeViewController.h"
现在运行你的app你就会看到下面的截图。
如果你视图关闭model view (模态视图),它将不能正常工作,很显然,我们利用RecipeViewController的"close" 实现离开的方法,只要在RecipeViewController.m中编辑下面的代码就可以实现了
- (IBAction)close:(id)sender{
[self dismissViewControllerAnimated:YES completion:NULL];
}
这个dismissViewControllerAnimated方法告诉视图控制器推出。再次运行程序,你就可以实现推出了。
处理多个选择
UICollectionView支持单一和多个选择。但是,在默认情况下,是单个选择。UICollectionView类中的allowsMultipleSelection属性控制是否支持同时多个选择。要启动多个选择,关键是要将属性设置为YES。
为了给你更好的想法关于怎样实现多个选择,我们将继续调整应用程序。用户允许选择的图片分享到facebook上面,按照下面的步骤可以完成
点击导航栏中的"share"按钮,然后button变成"Upload"。
用户选择recipe photos分享
在选择之后,用户点击"Upload"按钮。这个应用程序弹出对话框。
注:关于分享到facebook你可以看看这里的教程Facebook sharing tutorial
设计用户界面
首先要做的是添加"share"按钮。到storyboard的对象库中拖一个bar button item添加到conllection view controller的navigation bar上。如下图:
就像前面讲的,建立RecipeCollectinViewConteoller.h和"share"按钮的链接,property命名为"shareButton",给share button添加action 方法。
在RecipeCollectionViewController.h添加代码,就像下面的一样
@interface RecipeCollectionViewController:UICollectionViewController
@property (weak,nonatomic)IBOutlet UIBarButtonItem *shreButton;
- (IBAction)shareButtonTouched:(id)sender;
回到代码
这个应用程序提供了两种模式:单选和多选,当用户点击"share" 按钮,这个应用程序就进入多选模式,允许用户选择多张照片进行共享。为了支持多选模式,然后在RecipeCollectionViewController.m中添加两个变量
shareEnabled-这是一个布尔变量来标识是否选择这个模式,如果让被设置为YES,表示"share" 按钮被窃听同时启用多选
selectedRecipes-这是用来存储所选择的recipe上的数组
你的代码应该向下面的一样
@inreface RecipeCollectionViewController(){
NSArray *recipeImages;
BOOL shareEnabled;
NSMutableArray *selectedRecipes;
}
此外,添加下面的代码到viewDidLoad方法中,初始化数组
selectedRecipes = [NSMutableArray array];
管理项目的选择和取消
UICollectionViewDelegate协议定的方法,允许你管理在 collection view中的item的选择高亮。当用户选择一个项目时collectionView:didSelectItemAtIndexPath:方法被调用。我们需要实现这个方法,并添加到selectedRecipes 数组。将下面的代码添加到@end之前。
- (void)collectionView:(UICollectionView *)collectionView didiSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (shareEnabled){
//通过使用indexPath确定选定项目
NSString *selectedRecipe = [recipeImages[indexPath.section]objectAtIndex:indexPath.row];
//添加所选项目到数组中
[selectedRecipes addObject:selectedRecipe];
}
}
UICollectionViewCell类提供了一个属性来设置所选项目的背景图。为了表示项目被选中,我们通过改变collectionViewcell的背景图像来表示(即photo-frame-selected.png)。只要下面的collectionView:cellForItemAtIndexPath:方法中添加下面的代码:
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"photo-frame-selected.png"]];
不仅仅要实现持有状态啊,当然要有取消的状态啊。出于任何原因,用户可能取消一个项目。当一个项目被取消,那个应该重selectedRecipes数组中删除。因此我们应该将下面的代码添加到上面的方法中:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (shareEnabled){
NSString *deSelectedRecipe = [recipeImages[indexPath.section] objectAtIndex:indexPath.row];
[selectedRecipes removeObject:deSelectedRecipe];
}
}
下一步,当用户点击share按钮,我们将实现去shareButtonTouched:方法,我们接下来去编辑下面的代码:
- (IBAction)shareButtonTouched:(id)sender{
if (shareEnabled){
//传输选中的图片到facebook
if ([selectedRecipes count] >0){
if([SLComposeViewController isAvailableForServiceType:SLServiewTypeFacebook]){
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controller setInitialText:@"Check out my recipes!"];
for (NSString *recipePhoto in selectedRecipes){
[controller addImage:[UIImage imageNamed:recipePhoto]];
}
[self presentViewController:controller animated:YES completion:Nil];
}
}
//取消选定项目
for(NSIndexPath *indexPath in self.collectionView.indexPathForSelectedItems){
[sefl.collectionView deselectItemAtIndexPath:indexPath animated:NO];
}
//从selectedRecipes数组中删除所有项目
[selectedRecipes removeAllObjects];
//改变共享模式为NO
shareEnabled = NO;
self.collectionView.allowsMultipSelection = NO;
self.shareButton.title = @"Share";
[self.shareButton setStyle:UIBarButtonItemStylePlain];
} else {
//更改shareEnabled为YES ,改变按钮的文本为DONE
shareEnabled = YES;
self.collectionView.allowMultipleSelection = YES;
self.shareButton.title = @"Upload";
[self.shareButoon setStyle:UIBarButtonItemStyleDone];
}
}
为了帮助你理解上面的代码,我们解释一下
最后四行代码:如果共享模式最初是禁用的,我们把应用程序变成共享模式,使多个选择。与此同时,我们改变按钮的标题为“Upload”。
第一段代码:在共享模式下,用户点击“Upload”按钮后,我们将调出Facebook的composer。该SLComposeViewController附带了一些内置的方法,让您轻松上传多张照片。我们只需使用“ addImage ”方法来附加的图像。
第二个for 语句:稍后上传到facebook,取消选定项目,并从 selectedRecipes数组中删除它们。
改变共享模式为NO :则我们切换到单一选择模式。
作为“ SLComposeViewController ”是由社会框架提供的类,记得在“ RecipeCollectionViewController.m ”的最顶端导入Social.h文件
#import<Social/Social.h>
默认情况下我们项目中时没有添加Scoial.framework的,所以我们要添加。
快要完成了,但是,应用程序可能没办法运行,会出现一个错误。切换到共享模式后,当你选择任意的图片共享模式就会出现。这不是我们想要的,为了解决这个问题,我们需要使用shouldPerformSegueWithIdentifier方法来控制什么时候实现,那么就要添加下面的代码
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if (shareEnabled){
return NO;
}else{
reutrn YES;
}
}
完成了,如果你运行代码,你就可以看到下面的运行截图。
你可以从这里下载download the complete Xcode project from here代码。
来源:oschina
链接:https://my.oschina.net/u/723760/blog/221918