iOS - 关于点击小图查看大图的封装(包含单击、双击、捏合手势)

来源:互联网 发布:大宝眼霜 知乎 编辑:程序博客网 时间:2024/04/29 03:45

这次的封装,最终效果就是可以滑动查看所有图片,单击返回、双击放大/缩小、捏合放大/缩小的手势。在此,封装了三个类。如下所示:

第一个类(我们直接要使用的类):

#import "ImageScanCell.h"


@interface ImageScanController : BaseController


//1.图片数组(一组图片,是给collectionView现实的)

@property(nonatomic,strong)NSArray * imageURLStringArray;


//2.当前是哪个item被点击,就显示哪个item的图片

//如何得知哪个item'被点击,传递当前item的索引位置

@property(nonatomic,strong)NSIndexPath * selectedIndexPath;


@property (nonatomic,assign) NSInteger currentPage;

@end


// .m中

#import "ImageScanController.h"


@interface ImageScanController ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

{

    //子视图

    UICollectionView * _collectionView;

    

    //取非

    BOOL  _isHidden;

    

    // 需要下载的图片

    UIImage * _myImage;

    

    UIPageControl *_page;

    

}

@end


static NSString * imageScanID =@"ImageScanCell";


@implementation ImageScanController


- (void)viewDidLoad {

    [super viewDidLoad];

    

    

    self.title =@"图片浏览";

    

    self.view.backgroundColor = [UIColor whiteColor];

    

    

    //创建子视图

    [self _loadSubViews];

    

    //创建下载的按钮

    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];

    [button setImage:[UIImage imageNamed:@"img_download_p"] forState:UIControlStateNormal];

    [button addTarget:self action:@selector(downloadImageAction:) forControlEvents:UIControlEventTouchUpInside];

    button.frame = CGRectMake(kScreenWidth - 60 -20, kScreenHeight - 60 - 64 -30, 60,60);

    [self.view addSubview:button];

    

    //注册成为kNavigationBarHideOrNot这条通知的观察者

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(hideNavigationOrNot:) name:@"HideOrNot" object:nil];

    

}


#pragma mark - button action


- (void)downloadImageAction:(UIButton *)sender{

    //实现下载图片到相册(保存)

    

    //C语言有一个函数

    //参数一:要保存哪张图片

    //参数二:回调目标,当这个函数走完之后,会由哪个对象(当前这个参数),去调用一个什么方法(后面参数三的方法)

    //参数三:@selector 方法签名,是要被调用的方法的名字(文档中有给定的方法)

    //参数四:指要传递的信息,一般是NULL

    

    //回调方法注意看文档。

    UIImageWriteToSavedPhotosAlbum(_myImage, self,@selector(image: didFinishSavingWithError:contextInfo:),NULL);

    

}



- (void)               image: (UIImage *) image

    didFinishSavingWithError: (NSError *) error

                 contextInfo: (void *) contextInfo{

    

    //根据不同的情况,让提示视图提示消息显示不同的内容。

    NSString * message = nil;


    if (error ==nil ) {

        

        message = @"保存成功";

    } else{

        

        message = @"保存失败";

    }

    

    // 创建提示视图,通知用户是否保存成功

    UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil,nil];

    

    [alertView show];


}



#pragma mark - notification Action

- (void)hideNavigationOrNot:(NSNotification *)notification{

    _isHidden = !_isHidden;

    

    // 隐藏 显示导航栏

    [self.navigationController setNavigationBarHidden:_isHidden animated:YES];

    

    [self dismissViewControllerAnimated:NO completion:nil];

}


#pragma mark - remove observer

- (void)dealloc{

    

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"HideOrNot" object:nil];

}



#pragma mark - private action


- (void)_loadSubViews{

    

    //创建布局对象

    UICollectionViewFlowLayout * flow = [[UICollectionViewFlowLayout alloc]init];

    

    flow.itemSize = CGSizeMake(kScreenWidth, kScreenHeight);

    flow.minimumLineSpacing = 0;

    flow.minimumInteritemSpacing = 0;

    

    flow.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    

    //创建collectionView

    _collectionView = [[UICollectionView alloc]initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flow];

    

    _collectionView.dataSource = self;

    _collectionView.delegate = self;

    

    _collectionView.pagingEnabled = YES;

    

    [self.view addSubview:_collectionView];

    

    //注册单元格

    [_collectionView registerClass:[ImageScanCell class] forCellWithReuseIdentifier:imageScanID];

    

    

    UIPageControl *page = [[UIPageControl alloc] initWithFrame:CGRectMake((self.view.frame.size.width-150)/2,self.view.frame.size.height-20,150, 20)];

    page.numberOfPages = self.imageURLStringArray.count;

    page.backgroundColor = [UIColor clearColor];

    page.currentPageIndicatorTintColor = [UIColor whiteColor];

    page.pageIndicatorTintColor = [UIColor grayColor];

    [self.view addSubview:page];

    page.currentPage = self.currentPage;

    _page = page;


    

    

}


- (void)setImageURLStringArray:(NSArray *)imageURLStringArray{

    

    if (_imageURLStringArray != imageURLStringArray) {

        

        _imageURLStringArray = imageURLStringArray;

    }

    

    //[self _loadSubViews];

}


- (void)setSelectedIndexPath:(NSIndexPath *)selectedIndexPath{

    

    if (_selectedIndexPath != selectedIndexPath) {

        _selectedIndexPath = selectedIndexPath;

    }

}



#pragma mark - collection view  data source


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

    

    return _imageURLStringArray.count;

}



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

    

    //创建单元格

    ImageScanCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:imageScanID forIndexPath:indexPath];

    

    //cell.backgroundColor = [UIColor redColor];

    

    //传数据

    cell.imageURLString = _imageURLStringArray[indexPath.row];

    

    return cell;

}



//点击放大然后滑倒其他界面后,让原本的界面上的图片变小

//结束在界面显示的单元格的索引

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{

    

    //NSLog(@"当前是第%ld个图片", indexPath.row);

    //判断这个方法中的 indexPath对应的这个滑动视图(图片),是否有被放大

    

    //拿到 indexPath所对应的单元格上面的滑动视图

    

    //根据参数拿到这个单元格

    ImageScanCell * scanCell = (ImageScanCell *) cell;

//    if ( scanCell.imageScrollView.zoomScale > 1) {

//        

//        [scanCell.imageScrollView setZoomScale:1.0 animated:YES];

//    }else if(scanCell.imageScrollView.zoomScale < 1) {

//        

    [scanCell.imageScrollView setZoomScale:1.0 animated:YES];

    

//    }

    

}


//将要展示单元格是哪个,索引位置

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{


    //拿到当前显示的单元格对象

    ImageScanCell * myCell = (ImageScanCell *)cell;

    

    //拿到当前单元格显示的图片

    _myImage =  myCell.imageScrollView.imgView.image;

    

    

}


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    

    NSInteger pageCurrent = scrollView.contentOffset.x/kScreenWidth;

    

    _page.currentPage = pageCurrent;

}


#pragma mark - view life cycle

- (void)viewWillAppear:(BOOL)animated{

    

    [super viewWillAppear:animated];

    

    //视图将要出现, collectionViewview子视图,我也要出现了,

    //本来是出现第0个索引位置的单元格

    

    //我们复写这个方法,改变当前即将要现实的单元格

    

    //我们指定让collectionView滑动到指定位置的单元格

    

    //参数一:指定的单元格索引

    //参数二:滑动停止后的视图显示位置(枚举值)

    [_collectionView scrollToItemAtIndexPath:_selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally

     animated:YES];

}


第二个类:--------------------------------------------------------

#import <UIKit/UIKit.h>


@interface ScrollImageView : UIScrollView<UIScrollViewDelegate>


//1.子视图

@property(nonatomic,strong)UIImageView * imgView;


//2.显示数据

@property(nonatomic,copy)NSString * imageURLString;


@end





#import "ScrollImageView.h"


@implementation ScrollImageView

- (id)initWithFrame:(CGRect)frame{

    

    self = [super initWithFrame:frame];

    

    if (self) {

        

        //加载子视图


        _imgView = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];


        

        /**

         

          UIViewContentModeScaleToFill,

         UIViewContentModeRedraw,

        };


         */

         _imgView.contentMode = UIViewContentModeScaleToFill;


        

        

        //用户响应时间

        _imgView.userInteractionEnabled = YES;

       // _imgView.backgroundColor = [UIColor yellowColor];

        

        [self addSubview:_imgView];

        

        

        //自己的属性设置

        self.minimumZoomScale =0.5;

        self.maximumZoomScale =3.0;

        

        //设置代理(自己成为自己的代理,来实现缩放功能)

        self.delegate =self;

        

        

        //添加手势

        UITapGestureRecognizer * tapOnce = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(hidesOrNotAction:)];

        tapOnce.numberOfTapsRequired = 1;//默认是1,所以这行代码可省

        //添加到滑动视图上面(先把 imageView用户交互事件打开)

        [self addGestureRecognizer:tapOnce];

        

        

        //双击手势

        UITapGestureRecognizer * doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(doubleTapAction:)];

        doubleTap.numberOfTapsRequired = 2;

        

        [self addGestureRecognizer:doubleTap];


        //这个方法是为了防止两个手势的冲突当双击的时候,会冲突单击的方法,

        //让冲突的手势不响应

        //当我们单击的时候,让双击不响应

        [tapOnce requireGestureRecognizerToFail:doubleTap];

        

    }

    

    returnself;

}



- (void)setImageURLString:(NSString *)imageURLString{

    

    if (_imageURLString != imageURLString) {

        _imageURLString = imageURLString;

    }

    

    //赋值(图片)

    [_imgView setImageWithURL:[NSURL URLWithString:_imageURLString]];

    

    

    // 安全判断,如果没有图片的话,加载默认的图片

    if (!_imgView.image) {

        _imgView.image = [UIImage imageNamed:@"default_image.png"];

    }

    

}


#pragma mark - tap action

//隐藏导航栏

// 当前我们是在滑动视图这个视图类中,,没有导航控制器

//导航控制器 --控制器容器

- (void)hidesOrNotAction:(UITapGestureRecognizer *)tap {

    

    //发通知告诉 imageScanController,你要隐藏或者是显示导航栏

    [[NSNotificationCenter defaultCenter] postNotificationName:@"HideOrNot" object:nil];

}


//双击实现放大或者缩小

- (void)doubleTapAction:(UITapGestureRecognizer *)tap{


    if (self.zoomScale >1) {


        [self setZoomScale:1.0 animated:NO];

    } else{

        

        [self setZoomScale:2.0 animated:NO];

    }

    

}

#pragma mark - delegate

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{


    return _imgView;

}



第三个类:----------------------------------------------------------------

#import <UIKit/UIKit.h>


#import "ScrollImageView.h"


@interface ImageScanCell : UICollectionViewCell

//子视图(自己封装的滑动视图)

//测试界面效果,我们先给一个imageView

@property(nonatomic,strong)ScrollImageView * imageScrollView;

//数据

@property(nonatomic,copy)NSString * imageURLString;


@end




#import "ImageScanCell.h"


@implementation ImageScanCell


//代码方式

- (id)initWithFrame:(CGRect)frame{

    

    self = [super initWithFrame:frame];

    

    if (self) {

        

    

        //加载子视图

        

        _imageScrollView = [[ScrollImageView alloc]initWithFrame:CGRectMake(0,0, kScreenWidth, kScreenHeight)];

        _imageScrollView.pagingEnabled = NO;

        //_imageScrollView.backgroundColor = [UIColor greenColor];

        [self.contentView addSubview:_imageScrollView];

        

    }

    

    returnself;

}


- (void)setImageURLString:(NSString *)imageURLString{

    

    if (_imageURLString != imageURLString) {

        

        _imageURLString = imageURLString;

    }

    

 

    //传递数据滑动视图

    _imageScrollView.imageURLString = _imageURLString;

    

}


--------------OK,到此结束---------------------------
0 0