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
#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];
//视图将要出现, collectionView是view子视图,我也要出现了,
//本来是出现第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;
}
- iOS - 关于点击小图查看大图的封装(包含单击、双击、捏合手势)
- iOS--手势控制的使用:单击、双击、长按、滑动、托移、捏合、晃动。。
- iOS 关于UITapGestureRecognizer 单击与双击手势冲突的解决
- iOS常见手势总结-单击、双击、捏合、旋转、移动、清扫、长按
- 手势控制的使用:单击、双击、长按、滑动、托移、捏合、晃动
- iOS - 关于点击小图片之后查看对应大图的实现
- ios 单击和双击手势
- iOS中单双击,滑动和捏合手势的实现原理
- ios开发-单击和双击手势的区分处理
- ios开发-单击和双击手势的区分处理
- JQuery【点击小图查看大图】
- html点击小图查看大图
- ios中模拟手势单击或是双击
- iOS点击查看大图的动画效果
- iOS点击查看大图的动画效果
- IOS Gesture手势(点击、捏合、滑动、长按、旋转、拖动)
- iOS添加单击手势与tableview点击的冲突问题
- iOS 单击手势和双击手势共存问题
- Python读取文件的一行之linecache模块
- jQuery笔记--样式篇
- Java拦截器和过滤器的详解
- zabbix实战--web UI相关概念以及工作原理
- Android的消息机制概述即Handler的运行机制
- iOS - 关于点击小图查看大图的封装(包含单击、双击、捏合手势)
- 设计富客户端应用
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- text-shadow
- ProNet:Learning to propose object-specific Boxes for Cascaded Neural Networks
- android 处理运行时变更
- Tomcat服务器虚拟目录的映射方式
- Java的wait(), notify()和notifyAll()使用小结
- 软考助手V1.8上线啦[耶]