zoukankan      html  css  js  c++  java
  • 九宫格排列与浏览的简单功能

    一、九宫格布局

      在浏览各种微博、QQ空间、在网购等时候都可以注意到显示的图片是由九宫格来布局完成的。开发者为其限定了最大个数--9。当然,有一张就添加一张,最多不过九张。那就拿微博为例来实现其功能。以下是其初始的图。

    二、代码及实现效果

    (1)步骤:

    1. 新建一个工程,并创建一个WBImageView的类,使其继承于UIView。
    2. 创建一个WBImageItem类,继承于UIImageIView。
    3. 根据设置的背景图片循环创建九个imageView的位置。计算每个iamgeView的位置和大小(包括高度的计算)。
    4. 而后,给ImageItem添加手势,可以放大浏览,放大的时候需要记录原始的frame,方便恢复原样。还可以缩小回原图原位置,方法的要获取新的坐标系统的frame。这一些代码可以写在item里面。
    5. 关于图片滑动,就是将图片加载到scrollView上,滑动之后获取对应的index,在缩小(返回原始)的时候恢复在对应的位置。如图

      在做的过程中需要注意的地方就是:1.数据的传值问题(_imageList数组);2.在放大之后又要返回,则需要记住其原始的位置和大小;3.在变换的时候需要用到转换坐标系方法--- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;);4.图片都是放在scrollView上的,可以进行放大缩小滑动;5.在放大之后,注意一些细节问题--隐藏的要显示,而后将其放回原父视图上;6.缩小的道理只是将放大过程逆向返回。

      读者看到的放大过程,就是图片放大了,达到一定的大小之后就隐藏了(右侧图),而已经添加到scrollView上的就会显示出来(左侧图),这就是错觉,以为是一张图,其实是两张。所以要隐藏,完成放大之后要显示。同样 缩小的也是这个原理。

        

     (2)导入的头文件:

    1 //WBImageView.h 中
    2 #import "WBImageView.h"
    3 #import "WBImageItem.h"
    4 #import "UIImageView+WebCache.h"//针对于ImageView的第三方
    1 //WBImageViewController中
    2 #import "WBImageViewController.h"
    3 #import "WBImageView.h"
    4 #import "UIImageView+WebCache.h"

    (3)主要代码

    viewController.m 

     1 //在viewDidLoad中
     2 WBImageView *wbImageView = [[WBImageView alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 300)];
     3     
     4     wbImageView.backgroundColor = [UIColor orangeColor];
     5     //图片的链接
     6     wbImageView.imageList = @[
     7                               @"http://a.vpimg2.com/upload/merchandise/20348/W-TU-3122934087-33-1.jpg",
     8                               @"http://img.kumi.cn/photo/5a/15/b7/5a15b7cb955fb13e.jpg",
     9                               @"http://pic.nipic.com/2007-11-09/2007119122519868_2.jpg",
    10                               @"http://pic.nipic.com/2007-11-09/200711912230489_2.jpg",
    11                               @"http://www.xxjxsj.cn/article/UploadPic/2009-10/2009101018545196251.jpg",
    12                               @"http://pica.nipic.com/2008-03-19/2008319183523380_2.jpg",
    13                               @"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg",
    14                               @"http://h.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c812f9fe0e1be3eb13533fa400b.jpg",
    15                               @"http://pic27.nipic.com/20130201/3789536_092151001379_2.jpg"                              
    16                               ];
    17     
    18     [self.view addSubview:wbImageView];

     WBImageIvew.m 

     1 #warning 用class 声明一下  否则会循环引用
     2 @class WBImageItem;
     3 @interface WBImageView : UIView
     4 @property (nonatomic, copy) NSArray *imageList;//存放图片的数组
     5 /**
     6  *  方法说明:返回做缩小动画时  获取做动画的item
     7  *
     8  *  @param  currentIndex:大图浏览时浏览到的图片的位置
     9  *
    10  *  @return
    11  */
    12 - (WBImageItem *)getItemForIndex:(int)currentIndex;

     WBImageIvew.h中要设置一个NSArray属性,来保存外部传入的URL。

     1 #define kItemWH (self.frame.size.width -20)/3
     2 #define kItemSpace 10
     3 
     4 @implementation WBImageView
     5 {    
     6     WBImageItem *_item;
     7 }
     8 - (id)initWithFrame:(CGRect)frame {
     9     if (self = [super initWithFrame:frame]) {
    10     }
    11     return self;
    12 }
    13 
    14 - (void)setImageList:(NSArray *)imageList {
    15     _imageList = imageList;
    16     [self creatSubviews];
    17 }
    18 
    19 //创建图片
    20 - (void)creatSubviews {
    21     int  index = 0;
    22     for (NSString *url in _imageList) {
    23         _item = [[WBImageItem alloc] initWithFrame:[self getItemFrameAtIndex:index]];
    24 //        [_item setImageWithURL:[NSURL URLWithString:url]];        
    25         _item.backgroundColor = [UIColor greenColor];        
    26         _item.tag = 1000 + index;
    27         
    28         //传值给item的imageList属性
    29         _item.imageList = _imageList;
    30         
    31         //需要给 原始的赋值才可以显示在controller中
    32         _item.originFrame = _item.frame;
    33         _item.originSupview = self;
    34         _item.index = index;
    35         
    36         [self addSubview:_item];        
    37         index ++;
    38     }    
    39     CGFloat height = [self getWBImageViewHeight:(int)_imageList.count];    
    40     CGRect frame = self.frame;
    41     frame.size.height = height;    
    42     self.frame = frame;
    43     
    44 }
    45 
    46 - (CGRect)getItemFrameAtIndex:(int)index {
    47     /*
    48      0-2  x: index*(宽+间距)
    49           y: 0     
    50      3-5  x: (index%3)*(宽+间距)
    51           y: (高+间距)     
    52      6-8  x: (index%3)*(宽+间距)
    53           y:(index/3)(高+间距)
    54      */      
    55     CGFloat x = index % 3 * (kItemWH + kItemSpace);
    56     CGFloat y = index / 3 * (kItemWH + kItemSpace);
    57     
    58     return CGRectMake(x, y, kItemWH, kItemWH);
    59 }
    60 + (CGFloat)getWBImageViewHeight:(int)count {
    61         /*
    62      1-3 1*kItemWH
    63      4-6 2*kItemWH + 1*kItemSpace
    64      7-9 3*kItemWH + 2*kItemSpace     
    65      */    
    66     CGFloat height = ((count - 1) / 3 +1 ) * kItemWH + (count - 1) / 3 * kItemSpace;    
    67     return height;
    68 }
    WBImageView

     WBImageItem.h设置一些属性用于存储接收等。

     1 //避免循环引用
     2 @class WBImageView;
     3 @interface WBImageItem : UIImageView
     4 @property (nonatomic, copy)NSArray *imageList;//存放图片的数组
     5 @property (nonatomic, assign) int index;// item在父视图上的位置
     6 @property (nonatomic, assign) CGRect originFrame;//在原始父视图上的原始坐标
     7 @property (nonatomic, strong) WBImageView *originSupview;//item原始的父视图
     8 /**
     9  *  方法说明: 获取item 在新的坐标系统 (新的界面)上的frame
    10  *
    11  *  @param  originFrame:item原始的frame
    12  *
    13  *  @return
    14  */
    15 - (CGRect)getItemFrameAtWindow:(CGRect)originFrame;

    WBImageItem.m的代码如下。

     1 #import "WBImageItem.h"
     2 #import "WBImageViewController.h"
     3 #import "UIView+UIViewController.h"
     4 
     5 @implementation WBImageItem
     6 - (id)initWithFrame:(CGRect)frame {    
     7     if (self = [super initWithFrame:frame]) {
     8         //开启触摸
     9         self.userInteractionEnabled = YES;
    10         //禁止拉伸
    11         self.contentMode = UIViewContentModeScaleAspectFit;        
    12         [self addGesture];        
    13     }
    14     return self;    
    15 }
    16 
    17 //点击手势
    18 - (void)addGesture {    
    19     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];    
    20     //添加点击手势
    21     [self addGestureRecognizer:tap];    
    22 }
    23 
    24 - (void)tapAction {    
    25     WBImageViewController *controler = [[WBImageViewController alloc] init];    
    26     controler.imageList = _imageList;    
    27     //将点击的图片设置为大图,浏览当前图片,用来做动画
    28     controler.currentItem = self;
    29     controler.currentIndex = self.index;    
    30     [self.viewController presentViewController:controler animated:NO completion:nil];
    31 }
    32 - (void)setImageList:(NSArray *)imageList {    
    33     _imageList = imageList;
    34 }
    35 /**
    36  *  方法说明: 获取item 在新的坐标系统 (新的界面)上的frame
    37  *
    38  *  @param  originFrame:item原始的frame
    39  *
    40  *  @return
    41  */
    42 - (CGRect)getItemFrameAtWindow:(CGRect)originFrame {
    43     
    44     CGRect newFrame = [self.superview convertRect:originFrame toView:self.window];
    45     
    46     return newFrame;
    47 }
    48 @end

    WBImageViewController.h设置属性

    1 @property (nonatomic, copy) NSArray *imageList;
    2 @property (nonatomic, strong) WBImageItem *currentItem;//点击的图片显示在当前页面
    3 @property (nonatomic, assign) int currentIndex;//当前在浏览界面看到的图片位置属性
    4 // 1. 刚刚进入时 currentItem.index
    5 // 2. 根据scrollView  的滚动的偏移量计算

    WBImageViewController.m双击放大(缩小)要返回图片,利用图片的tag值(- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView)来获取。

      1 #define kSelfViewWidth self.view.frame.size.width
      2 #define kSelfViewHeight self.view.frame.size.height
      3 @interface WBImageViewController ()
      4 {
      5     UIScrollView *_supScrollView;//图片的滚动浏览视图    
      6     NSMutableArray *_subScroollViews; 
      7 }
      8 @end
      9 
     10 @implementation WBImageViewController
     11 - (void)viewDidLoad {
     12     [super viewDidLoad];    
     13     //把当前页面的item 放到当前的页面
     14     self.currentItem.frame = [self.currentItem getItemFrameAtWindow:self.currentItem.originFrame];    
     15     [self.view.window addSubview:self.currentItem];
     16 #warning 需要在 item中给原始的originFrame赋值    
     17     [self.view addSubview:self.currentItem];    
     18     [self createSubviews];   
     19 }
     20 
     21 - (void)viewDidAppear:(BOOL)animated {
     22     [super viewDidAppear:animated];
     23     //放大动画
     24     [UIView animateWithDuration:.35 animations:^{        
     25         self.currentItem.frame = self.view.bounds;
     26     }  completion:^(BOOL finished) {        
     27         //动画结束之后,显示
     28         _supScrollView.hidden = NO;        
     29         //放回原父视图上
     30         self.currentItem.frame = self.currentItem.originFrame;
     31 #warning 虽然在.h中已经导入,但是还需导入
     32         WBImageView *wbImageView = self.currentItem.originSupview;        
     33         [wbImageView addSubview:self.currentItem];
     34     }];    
     35 }
     36 
     37 //获取imageList的传值 不调用set的话 ,可以直接使用 _imageList = self.imageList;
     38 - (void)setImageList:(NSArray *)imageList {    
     39     _imageList = imageList;
     40 }
     41 
     42 - (void)createSubviews {    
     43 //   1. 初始化图片浏览的scrollView
     44     _supScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];    
     45     _supScrollView.delegate = self;    
     46     _supScrollView.pagingEnabled = YES;//翻页    
     47     //默认隐藏,否则会出现两张图片
     48     _supScrollView.hidden = YES;    
     49     _supScrollView.contentSize = CGSizeMake(kSelfViewWidth * _imageList.count, kSelfViewHeight);    
     50     _supScrollView.contentOffset = CGPointMake(kSelfViewWidth * self.currentIndex, 0);    
     51     [self.view addSubview:_supScrollView];    
     52 //   2.创建图片的显示控件    
     53     _subScroollViews = [[NSMutableArray alloc] init];    
     54     int index = 0;
     55     for (NSString *url in _imageList) {        
     56         //第一层scrollView
     57         UIScrollView *subScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kSelfViewWidth * index, 0, kSelfViewWidth, kSelfViewHeight)];
     58         subScrollView.contentSize = CGSizeMake(kSelfViewWidth, kSelfViewHeight);        
     59         subScrollView.delegate = self;        
     60         //设置放大缩小倍数
     61         subScrollView.maximumZoomScale = 2.f;
     62         subScrollView.minimumZoomScale = .5f;        
     63         [_supScrollView addSubview:subScrollView];
     64         [_subScroollViews addObject:subScrollView];       
     65         UIImageView *imageView = [[UIImageView alloc] initWithFrame:subScrollView.bounds];
     66         //禁止图片拉伸
     67         imageView.contentMode = UIViewContentModeScaleAspectFit;
     68         //默认是关闭的
     69         imageView.userInteractionEnabled = YES;        
     70         imageView.tag = 20001;        
     71         UIImageView *smallImageView = [[UIImageView alloc] initWithFrame:imageView.bounds];
     72         [smallImageView setImageWithURL:[NSURL URLWithString:url]];        
     73         NSString *largeImageUrl = [url stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"large"];        
     74         [imageView setImageWithURL:[NSURL URLWithString:largeImageUrl] placeholderImage:smallImageView.image];        
     75         [smallImageView removeFromSuperview];
     76         smallImageView = nil;        
     77         [subScrollView addSubview:imageView];        
     78         //添加点击手势
     79         UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)];
     80         [imageView addGestureRecognizer:tap1];
     81         //双击手势
     82         UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapActionTwo)];        
     83         //numberOfTapsRequired 点击的次数
     84         tap2.numberOfTapsRequired = 2;
     85         //numberOfTouchesRequired 触摸点的个数
     86         tap2.numberOfTouchesRequired = 1;
     87         [imageView addGestureRecognizer:tap2];
     88         //双击优先
     89         [tap1 requireGestureRecognizerToFail:tap2];
     90         index ++;
     91     }
     92 }
     93 
     94 //双击放大
     95 - (void)tapActionTwo {    
     96     UIScrollView *scrollView = [_subScroollViews objectAtIndex:self.currentIndex];    
     97     [UIView animateWithDuration:.35 animations:^{        
     98         scrollView.zoomScale = scrollView.zoomScale == 1.0f ? 2.0f : 1.0f;        
     99     }];   
    100 }
    101 
    102 //给图片一个点击手势,使其返回
    103 - (void)dismiss {    
    104     [self dismissViewControllerAnimated:NO completion:nil];    
    105     //缩小动画实现
    106     WBImageView *wbImageView = self.currentItem.originSupview;    
    107     WBImageItem *item = [wbImageView getItemForIndex:self.currentIndex];    
    108     //再次将图片放回到原来View上
    109     CGPoint newPoint = [self.view convertPoint:CGPointZero toView:wbImageView];
    110     //大小
    111     CGRect frame = item.frame;
    112     //位置=新的位置
    113     frame.origin = newPoint;
    114     //大小=屏幕大小
    115     frame.size = self.view.frame.size;
    116     //重新复制给item
    117     item.frame = frame;    
    118 //    动画实现
    119     [wbImageView bringSubviewToFront:item];    
    120     [UIView animateWithDuration:.35 animations:^{        
    121         item.frame = item.originFrame;
    122     }];
    123 }
    124 
    125 #pragma mark- UIScrollViewDelegate
    126 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    127         if (scrollView != _supScrollView) {        
    128         return [scrollView viewWithTag:20001];
    129     }
    130     return nil;
    131 }
    132 //此方法实现的是点击缩小之后,恢复到对应的原位置
    133 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    134     //要分清楚
    135     if (scrollView == _supScrollView) {
    136         //获得最新滚动的界面的index属性
    137         int newIndex = (int)scrollView.contentOffset.x/kSelfViewWidth;        
    138         if (self.currentIndex == newIndex) {            
    139             return;
    140         }else {            
    141             self.currentIndex = newIndex;
    142         }
    143     }    
    144 }
    145 
    146 @end
    View Code

    另外,在WBImageView.m中写一个方法,并开放出来,在WBImageViewController中缩小的时候使用。

     1 /**
     2  *  方法说明:返回做缩小动画时  获取做动画的item
     3  *
     4  *  @param  currentIndex:大图浏览时浏览到的图片的位置
     5  *
     6  *  @return
     7  */
     8 - (WBImageItem *)getItemForIndex:(int)currentIndex {    
     9     WBImageItem *item = (WBImageItem *)[self viewWithTag:1000 + currentIndex];    
    10     return item;    
    11 }

    以上需要第三方的文档。代码下载路径http://pan.baidu.com/s/1o6KQYAQ

    实现效果如下图 

    可以看到,图片大小不一样,这是设置了图片禁止拉伸的原因(self.contentMode = UIViewContentModeScaleAspectFit;

        UIViewContentModeScaleToFill,//以宽为基准,对高度进行对应比例拉伸或压缩

        UIViewContentModeScaleAspectFit,//不改变原来大小 

        UIViewContentModeScaleAspectFill,//以高为基准,对宽度进行对应比例拉伸或压缩

    以上文章是博主原创文章,转载请标明出处。

  • 相关阅读:
    [AX]AX2012激活HTTP适配器AIF端口提示错误“The deployment web site was not found for port”
    [AX]AX2012 嵌套使用Data contract class
    [AX]AX2012 对SSRS报表参数分组
    [AX]AX2012 SSRS报表的语言本地化
    [AX]AX2012 Number sequence framework :(二)实现自定义模块的Number sequence
    [AX]AX3中使用LedgerBalanceSum计算科目余额期间发生额
    [AX]AX2012 域管理员组成员没有权限部署报表
    [C#] 在C#中使用HOOK监视鼠标消息的问题
    服务器端获取客户端信息(时间 etc..)
    MSBuild version 与 ToolsVersion 的区别
  • 原文地址:https://www.cnblogs.com/david-han/p/4902529.html
Copyright © 2011-2022 走看看