文档章节

在Collection View中处理单个或多个选择

人生天地间
 人生天地间
发布于 2014/04/14 00:14
字数 2494
阅读 5047
收藏 4
点赞 0
评论 0

     在前面我们已经学过了UICollectionView的基本的东西。如果你没有看过你可以去看看前面的写的文章。

             正如前面提到的那样,Collection view和UITableView很相似,但我们将给你一个更好的方法去展示集合项目,例如处理单个或者多个项目进行交互。我们会继续使用前面的代码继续改进来完成下面的的要求:

  1.   为了演示如何处理单个的选择,我们将改进应用程序,当用户点击一个照片,这个应用程序就会跳出一个魔胎试图,并且能够以较大的尺寸显示照片。

  2. 我们可以实现分享

如下图显示:


Recipe App Multiple Selection

    这个应用程序很简单,不会给你带来任何设计奖项,但是它却可以给你提供了一个比较好的交互想法,如果你没有看过前面写的blog你可以选择在download this Xcode template这里下载。但是至少要在xcode4.6或以后的版本编辑才好。

  处理单个的选择

   首先,我们要改变应用程序来处理这个选择:当用户点击任一图片,这个应用都会弹出一个模态视图,以显示更加高画质的图片。

  设计用户界面

   首先,让我们来设计视图控制器来显示照片。到 stroyboard,从对象库中拖动一个ImageView到view controller,并分别设置高度为200和宽度为320。最后,添加一个导航栏到视图的顶部,并添加一个bar button item,并命名为"Colse",就像下面显示的:

Designing the Modal View Controller

    因为我们希望当用户点在collection view中击任何图片的时候,都要在视图控制器中显示,所以我们使用联线来链接collection view和view controller。按下Ctrl键,然后点击"Recipe View Cell“然后拖向视图控制器,选择"modal"风格,设置segue identifier为“showRecipePhoto”。

    

Segue Connection


        如果你现在运行你的应用程序,你你点击图片会跳转到一个空白界面,这是为啥勒,因为我们没有用代码去实现,模态视图不知道啥图片要显示,啥不显示所以不显示咯。所以我们要创建一个新的类(也是继承自UIViewController),命名为"RecipeViewController ",回到storyboard,选择刚刚创建的视图控制器并设置custom class为RecipeViewController,如图:

Set the custom class as RecipeViewController

      下一步,我们将刚刚建立的视图和RecipeViewController 链接,按住Ctrl键,点击image view并向RecipeViewController.h拖动。变量名为"recipeImageView"重复上面的步骤,并链接“close”到recipeViewController.h选择"action"。

   

Establish Variable Connection

  添加代码

     为了让其他控制器得到image name,我们也将添加一个"recipeImageName"属性,下面是RecipeViewController.h中的片段

    @interface  RecipeViewController:UIViewController

    @property (weak,nonatomic)IBOutlet UIImageView *recipeImageView;

    @property (weak,nonatomic)NSString *recipeImageName;

    - (IBAction)close:(id)sender;

   @end

   当显示的时候,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你就会看到下面的截图。

   

Recipe App - Single Selection

           如果你视图关闭model view (模态视图),它将不能正常工作,很显然,我们利用RecipeViewController的"close" 实现离开的方法,只要在RecipeViewController.m中编辑下面的代码就可以实现了

- (IBAction)close:(id)sender{

    [self dismissViewControllerAnimated:YES completion:NULL];

}

       这个dismissViewControllerAnimated方法告诉视图控制器推出。再次运行程序,你就可以实现推出了。


   处理多个选择

         UICollectionView支持单一和多个选择。但是,在默认情况下,是单个选择。UICollectionView类中的allowsMultipleSelection属性控制是否支持同时多个选择。要启动多个选择,关键是要将属性设置为YES。

     为了给你更好的想法关于怎样实现多个选择,我们将继续调整应用程序。用户允许选择的图片分享到facebook上面,按照下面的步骤可以完成

  1. 点击导航栏中的"share"按钮,然后button变成"Upload"。

  2. 用户选择recipe photos分享

  3. 在选择之后,用户点击"Upload"按钮。这个应用程序弹出对话框。

注:关于分享到facebook你可以看看这里的教程Facebook sharing tutorial


   设计用户界面

        首先要做的是添加"share"按钮。到storyboard的对象库中拖一个bar button item添加到conllection view controller的navigation bar上。如下图:

UICollectionView Multiple Selection Share Button

      就像前面讲的,建立RecipeCollectinViewConteoller.h和"share"按钮的链接,property命名为"shareButton",给share button添加action 方法。

UICollectionView Share Button IBAction

    在RecipeCollectionViewController.h添加代码,就像下面的一样

        @interface  RecipeCollectionViewController:UICollectionViewController

        @property (weak,nonatomic)IBOutlet UIBarButtonItem *shreButton;

       - (IBAction)shareButtonTouched:(id)sender;

        @end


 回到代码

         这个应用程序提供了两种模式:单选和多选,当用户点击"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"]];

       

Collection View Cell Selected

         不仅仅要实现持有状态啊,当然要有取消的状态啊。出于任何原因,用户可能取消一个项目。当一个项目被取消,那个应该重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的,所以我们要添加。

Collection View Adds Social Framework

       快要完成了,但是,应用程序可能没办法运行,会出现一个错误。切换到共享模式后,当你选择任意的图片共享模式就会出现。这不是我们想要的,为了解决这个问题,我们需要使用shouldPerformSegueWithIdentifier方法来控制什么时候实现,那么就要添加下面的代码

        - (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender

{

      if (shareEnabled){

          return NO;

   }else{

          reutrn YES;

   }

}


  完成了,如果你运行代码,你就可以看到下面的运行截图。

Recipe Collection App Facebook Deliverable

  你可以从这里下载download the complete Xcode project from here代码。

© 著作权归作者所有

共有 人打赏支持
人生天地间
粉丝 12
博文 46
码字总数 42083
作品 0
常州
程序员
SolrCloud5.0路由 Collection建与数据迁移

SolrCloud的设计是为了提供高可用、容错,在分布式环境中进行内容索引和查询请求。 SolrCloud 5.0,对自带的SolrCloud的启动脚本进行了改进,启动SolrCloud变的异常简单,执行 view sourcep...

zcl111
2016/07/14
13
0
Android中的数据结构和算法

Android客户端面试基础(五)-数据结构与算法- http://blog.csdn.net/johnWcheung/article/details/72843223 数据结构:是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之...

shareus
2017/12/18
0
0
android3.0 widget

本文翻译整理自:http://developer.android.com/guide/topics/appwidgets/index.html#preview 前言 在Android3.0中,增加了大量的APP Widgets功能,在本文中将详细介绍它们。 一,设置预览图片...

stefanliao
2012/05/26
0
0
通过UICollectionView创建网格布局

在这个教程中,我们经构建一个件的程序,以网格布局的俄方式现实图片集,你将学到下面的信息: UICollectionView简介 如何是使用UICollectionView构建一个简单的基于网格的布局 自定义Collect...

人生天地间
2014/04/10
0
0
Mybatis 映射文件配置

Mybatis参数传递和取值详情: 单个参数:Mybatis不会做特殊处理, #{参数名/任意名}:取出参数值。 多个参数:mybatis会做特殊处理。 1.多个参数会被封装成 一个map, 封装: key:paramName...

特拉仔
01/20
0
0
UICollectionView 使用 介绍

1.1. Collection View 全家福: UICollectionView, UITableView, NSCollectionView n 不直接等效于NSCollectionView n 也不替代UITableView----亲兄弟 为什么要使用Collection Views呢? n ......

hejunbinlan
2016/01/06
112
0
用 MongoDB 取代 RabbitMQ

RabbitMQ是当成应用比较广泛的队列服务系统,其配套的客户端和监控运维方案也比较成熟。BoxedIce的队列服务从今年四月开始从RabbitMQ切换到了MongoDB上,并一直稳定运行至今,下面是BoxedIc...

红薯
2011/10/10
9.5K
2
[翻译]在objective c创建自定义collection view样式

创建自定义collection样式 苹果在ios6中新增了一个更加易于创建和管理复杂用户界面的类:collection view。在此之前ios6上面用于展示多项列表的是table view,虽然名称是表格但它展示信息的形...

f1eming
2014/11/17
0
0
ObObjective-c 采集试图 UICollection

// // ViewController.m // 12.14 采集试图 UICollection // // Created by DC017 on 15/12/14. // Copyright © 2015年 DC017. All rights reserved. // #import "ViewController.h" @inter......

_pioneer_
2015/12/15
12
0
MongoDB集群部署

数据副本 MongoDB中的一组副本是一群mongod进程,这些进程维护同样的数据集。副本集提供了冗余和高可用性,是生产环境部署的基础。 数据冗余和可用性 通过在不同的服务器上存储相同的数据,副...

黄索远
2017/10/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

about git flow

  昨天元芳做了git分支管理规范的分享,为了拓展大家关于git分支的认知,这里我特意再分享这两个关于git flow的链接,大家可以看一下。 Git 工作流程 Git分支管理策略   git flow本质上是...

qwfys
今天
2
0
Linux系统日志文件

/var/log/messages linux系统总日志 /etc/logrotate.conf 日志切割配置文件 参考https://my.oschina.net/u/2000675/blog/908189 dmesg命令 dmesg’命令显示linux内核的环形缓冲区信息,我们可...

chencheng-linux
今天
1
0
MacOS下给树莓派安装Raspbian系统

下载镜像 前往 树莓派官网 下载镜像。 点击 最新版Raspbian 下载最新版镜像。 下载后请,通过 访达 双击解压,或通过 unzip 命令解压。 检查下载的文件 ls -lh -rw-r--r-- 1 dingdayu s...

dingdayu
今天
1
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
今天
2
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
今天
1
0
Java工具类—随机数

Java中常用的生成随机数有Math.random()方法及java.util.Random类.但他们生成的随机数都是伪随机的. Math.radom()方法 在jdk1.8的Math类中可以看到,Math.random()方法实际上就是调用Random类...

PrivateO2
今天
3
0
关于java内存模型、并发编程的好文

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

DannyCoder
昨天
1
0
dubbo @Reference retries 重试次数 一个坑

在代码一中设置 成retries=0,也就是调用超时不用重试,结果DEBUG的时候总是重试,不是0吗,0就不用重试啊。为什么还是调用了多次呢? 结果在网上看到 这篇文章才明白 https://www.cnblogs....

奋斗的小牛
昨天
2
0
数据结构与算法3

要抓紧喽~~~~~~~放羊的孩纸回来喽 LowArray类和LowArrayApp类 程序将一个普通的Java数组封装在LowArray类中。类中的数组隐藏了起来,它是私有的,所以只有类自己的方法才能访问他。 LowArray...

沉迷于编程的小菜菜
昨天
1
0
spring boot应用测试框架介绍

一、spring boot应用测试存在的问题 官方提供的测试框架spring-boot-test-starter,虽然提供了很多功能(junit、spring test、assertj、hamcrest、mockito、jsonassert、jsonpath),但是在数...

yangjianzhou
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部