zoukankan      html  css  js  c++  java
  • UICollectionViewController用法

    在iOS 6 发布前,开发人员习惯使用UITableView来展示几乎所有类型的数据集合。ios 6 为 IOS 引入了全新的控制器,用来显示数据集合,集合视图控制器是与表视图控制器类似的全新UI框架。。

     下面讲解下一些重要的类与协议,它们是你在实现集合视图时必须知道 的。

    • UICollectionViewController

    这个类的功能与UITableViewController类似。它负责管理集合视图、存储所需的数据,并且能处理数据源与委托协议。

    1、UICollectionViewCell

    它与UITableViewCell很像。你通常不需要创建UITableViewCell,可以调用 dequeueReusableCellWithReuseIdentifier:方法从集合视图中获取。

     MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:

                                          orientation == PhotoOrientationLandscape ? CellIdentifierLandscape:CellIdentifierPortrait

                                                                                   forIndexPath:indexPath];

    2、UICollectionViewDataSource

    猜到了吧,它与UITableViewDataSource方法类似。数据源协议拥有需要在UICollectionViewController的子类中实现的方法。

    3、UICollectionViewDelegate

     要在集合视图中处理选中或高亮事件,就得实现委托协议中的方法。

    下面能过具体的Demo向大家介绍下UICollectionViewController的用法:

     首先在Xcode中创建一个单视图应用。在第二个窗格中,选择Use Storyboards、Use Automatic Reference Counting以及Choose iPad as the target device复选框并点击Next按钮,然后再选择想要保存的位置。

    1、编辑 storyboard

     打开 MainStoryboard.storyboard文件并删除其中唯一的视图控制器。从对象库中拖出一个UICollectionViewController类。确保这个控制器被设置为故事板的初始视图控制器。

     现在,在工程中打开唯一的视图控制器的头文件。将基类从UIViewController改成 UICollectionViewController,并实现UICollectionViewDataSource 与 UICollectionViewDelegate协议。回到故事板,将集合视图控制器的类名改成MKViewController(或者使用任意其它的前缀)。构建并运行应用,ios模拟器中会出现一个黑色的屏幕。

    2、添加集合视图单元

    看到这样的结果并不能使你满足,对吧?我们来给它加点料吧。首先,添加一个UICollectionViewCell的子类。我们取名为MKPhotoCell。打开你的故事板并在集合视图控制器中选择唯一的集合视图单元。将它的类更改为MKPhotoCell.在Utilities(实用工具)窗格打开属性检查器并将标识符设置为 MKPhotoCell。这一步非常重要。在后面的代码中,你将会使用这个标识符来(dequeue)出列单元.如图所示:

    添加一个空白的UIView作为你的集合视图单元的子视图,并把视图背景色改为红色。

    3、实现数据源方法

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

      

      return100;

    }

    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {

        

        return 1;

    }

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

      

      MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:@"MKPhotoCell"

                                                                                   forIndexPath:indexPath];

      return cell;

    }

    现在构建并运行应用。你将会看到有100个单元的栅格,每一个单元都是红色的。很神奇吧,当你旋转iPad到横向时会更惊奇:栅格会自动旋转并对齐。

    4、显示图片

    现在可以用一些更加有趣的东西来替换这些红色的子视图。这里我们要显示某个目录中的图片。把一些图片大约50张复制到你的工程中去。移除在上一节中添加的红色子视图,并添加一个UIImageView和一个UILabel到UICollectionViewCell中。

    5、准备数据源

    实现方法是遍历目录中的文件。把它添加到集合视图控制器子类的viewDidLoad方法中。

      NSArray * photosArray = [[NSFileManagerdefaultManager] contentsOfDirectoryAtPath:[selfphotosDirectory] error:nil];

      self.photosList = photosArray;

    然后定义photosDirectory方法:

    -(NSString*) photosDirectory

    {

      return [[[NSBundlemainBundle] resourcePath] stringByAppendingPathComponent:@"Photos"];

    }


    现在,更新数据源方法,使其返回这些信息数据。上节代码返回的是一个区和100个项。将数值100改成self.photosList数组。

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:@"MKPhotoCell"

                                                                                   forIndexPath:indexPath];

        

      

      NSString *photoName = [self.photosList objectAtIndex:indexPath.row];

      NSString *photoFilePath = [[self photosDirectory] stringByAppendingPathComponent:photoName];

      cell.nameLabel.text =[photoName stringByDeletingPathExtension];

      

      UIImage *image = [UIImage imageWithContentsOfFile:photoFilePath];

      

      UIGraphicsBeginImageContext(CGSizeMake(128.0f, 128.0f));

      [image drawInRect:CGRectMake(0, 0, 128.0f, 128.0f)];

      cell.photoView.image = UIGraphicsGetImageFromCurrentImageContext();

            UIGraphicsEndImageContext();

      return cell;

    }

     

    现在构建并运行应用,你将会看到图片整齐地按照行列排列。

    6、支持横屏与竖屏图片

    在故事板中创建另一个UICollectionViewCell并将它的类更改为MKPhotoCell.改变图片视图的大小以适应竖屏,之前的旧的单元方向则是横屏。你可以为横屏使用180*120大小,为竖屏单元使用120*180大小。MKPhotoCell大小为200*250. 更改它们的cellIdentifier,比如改成MKPhotoCellLandscape 和 MKPhotoCellPortrait这样的。完成之后,故事板应该是这样的:

    7、判定方向

    现在你必须根据图片的方向来决定使用哪个单元。可以通过创建UIImage然后读取它的size属性来获取图片的方向。如果图片的宽度大于高度,则是横向;否则就是竖向。如果你在collectionView cellForItemAtIndexPath:方法中进行计算的话,滚动速度肯定会受影响,我们在viewDidLoad方法中计算。代码如下:

    - (void)viewDidLoad

    {

      [superviewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

      NSArray * photosArray = [[NSFileManagerdefaultManager] contentsOfDirectoryAtPath:[selfphotosDirectory] error:nil];

      self.photosCache = [NSMutableDictionarydictionary];

      self.photoOrientation = [NSMutableArrayarray];

      self.photosList = nil;

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

        

        [photosArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

          

          NSString *path = [[selfphotosDirectory] stringByAppendingPathComponent:obj];

          CGSize size = [UIImage imageWithContentsOfFile:path].size;

          if(size.width > size.height)

            [self.photoOrientationaddObject:[NSNumbernumberWithInt:PhotoOrientationLandscape]];

          else

            [self.photoOrientationaddObject:[NSNumbernumberWithInt:PhotoOrientationPortrait]];

        }];

        

        dispatch_async(dispatch_get_main_queue(), ^{

          

          self.photosList = photosArray;

          [self.collectionViewreloadData];

        });

      });

    }

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

      

      static NSString *CellIdentifierLandscape = @"MKPhotoCellLandscape";

      static NSString *CellIdentifierPortrait = @"MKPhotoCellPortrait";

      

      int orientation = [[self.photoOrientation objectAtIndex:indexPath.row] integerValue];

      

      MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:

                                          orientation == PhotoOrientationLandscape ? CellIdentifierLandscape:CellIdentifierPortrait

                                                                                   forIndexPath:indexPath];

        

      

      NSString *photoName = [self.photosList objectAtIndex:indexPath.row];

      NSString *photoFilePath = [[self photosDirectory] stringByAppendingPathComponent:photoName];

      cell.nameLabel.text =[photoName stringByDeletingPathExtension];

      

      __block UIImage* thumbImage = [self.photosCache objectForKey:photoName];

      cell.photoView.image = thumbImage;

      

      if(!thumbImage) {

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

          

          UIImage *image = [UIImage imageWithContentsOfFile:photoFilePath];

          if(orientation == PhotoOrientationPortrait) {

            UIGraphicsBeginImageContext(CGSizeMake(180.0f, 120.0f));

            [image drawInRect:CGRectMake(0, 0, 180.0f, 120.0f)];

            thumbImage = UIGraphicsGetImageFromCurrentImageContext();

            UIGraphicsEndImageContext();

          } else {

            

            UIGraphicsBeginImageContext(CGSizeMake(120.0f, 180.0f));

            [image drawInRect:CGRectMake(0, 0, 120.0f, 180.0f)];

            thumbImage = UIGraphicsGetImageFromCurrentImageContext();

            UIGraphicsEndImageContext();

          }

          

          dispatch_async(dispatch_get_main_queue(), ^{

            

            [self.photosCache setObject:thumbImage forKey:photoName];

            cell.photoView.image = thumbImage;

          });

        });

      }

      

      return cell;

    }

     

    构建并运行应用。应该可以横竖屏切换了。因为篇幅问题,暂不处理点击事件了。

    原文:http://www.cnblogs.com/javawebsoa/archive/2013/05/24/3098089.html 

  • 相关阅读:
    跳跃游戏
    不同路径
    最大子序和
    最长回文子序列
    最长公共子序列
    零钱兑换
    合并区间
    寻找数组的中心索引
    制造小程序中的一些经验
    h5写的一个签到积分系统
  • 原文地址:https://www.cnblogs.com/langtianya/p/4100907.html
Copyright © 2011-2022 走看看