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

冷暖自知 提交于 2020-03-02 18:44:52

     在前面我们已经学过了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代码。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!