XKZoomingView.h

#import <UIKit/UIKit.h>

@interface XKZoomingView : UIScrollView
/**
本地图片
*/
@property (nonatomic, strong) UIImage *mainImage; /**
图片显示
*/
@property (nonatomic, strong) UIImageView *mainImageView;
@end

XKZoomingView.m

#import "XKZoomingView.h"
@interface XKZoomingView()<UIScrollViewDelegate>
/**
当前图片偏移量
*/
@property (nonatomic,assign) CGPoint currPont;
@end
@implementation XKZoomingView - (instancetype)init{
self = [super init];
if (self) {
[self setup];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup{
self.backgroundColor = [[UIColor grayColor]colorWithAlphaComponent:0.2];
self.delegate = self;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.maximumZoomScale = ;
self.minimumZoomScale = ;
self.alwaysBounceHorizontal = NO;
self.alwaysBounceVertical = NO;
self.layer.masksToBounds = YES;
if (@available(iOS 11.0, *)) {
self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
[self addSubview:self.mainImageView]; _currPont = CGPointZero; ///监听屏幕旋转
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
///单击
UITapGestureRecognizer *tapSingle = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapSingleSponse:)];
//设置手势属性
tapSingle.numberOfTapsRequired = ;
tapSingle.delaysTouchesEnded = NO;
[self.mainImageView addGestureRecognizer:tapSingle];
///双击
UITapGestureRecognizer *tapDouble = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapDoubleSponse:)];
//设置手势属性
tapDouble.numberOfTapsRequired = ;
[self.mainImageView addGestureRecognizer:tapDouble];
///避免手势冲突
[tapSingle requireGestureRecognizerToFail:tapDouble];
} #pragma mark - layoutSubviews
- (void)layoutSubviews{
[super layoutSubviews];
///放大或缩小中
if (self.zooming || self.zoomScale != 1.0 || self.zoomBouncing) {
return;
} ///设置图片尺寸
if (_mainImage) {
CGRect imgRect = [self getImageViewFrame];
self.mainImageView.frame = imgRect;
///设置content size
if (CGRectGetHeight(imgRect) > CGRectGetHeight(self.frame)) {
[self setContentSize:CGSizeMake(CGRectGetWidth(self.frame), CGRectGetHeight(imgRect))];
}
else{
[self setContentSize:CGSizeMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame))];
}
} }
- (void)setMainImage:(UIImage *)mainImage{
_mainImage = mainImage;
self.mainImageView.image = _mainImage;
[self setContentOffset:CGPointMake(, )];
[self setNeedsLayout];
} /**
根据图片原始大小,获取图片显示大小
@return CGRect
*/
- (CGRect)getImageViewFrame{
if (_mainImage) {
CGRect imageRect;
CGFloat scWidth = self.frame.size.width;
CGFloat scHeight = self.frame.size.height;
///width
if (_mainImage.size.width > scWidth) {
imageRect.size.width = scWidth;
CGFloat ratioHW = _mainImage.size.height/_mainImage.size.width;
imageRect.size.height = ratioHW * imageRect.size.width;
imageRect.origin.x = ;
}
else{
imageRect.size.width = _mainImage.size.width;
imageRect.size.height = _mainImage.size.height;
imageRect.origin.x = (scWidth - imageRect.size.width)/;
}
///height
if (imageRect.size.height > scHeight) { imageRect.origin.y = ;
}
else{
imageRect.origin.y = (scHeight - imageRect.size.height)/;
}
return imageRect;
}
return CGRectZero;
}
/**
获取点击位置后所需的偏移量【目的是呈现点击位置在试图上】 @param location 点击位置
*/
- (void)zoomingOffset:(CGPoint)location{
CGFloat lo_x = location.x * self.zoomScale;
CGFloat lo_y = location.y * self.zoomScale; CGFloat off_x;
CGFloat off_y;
///off_x
if (lo_x < CGRectGetWidth(self.frame)/) {
off_x = ;
}
else if (lo_x > self.contentSize.width - CGRectGetWidth(self.frame)/){
off_x = self.contentSize.width - CGRectGetWidth(self.frame);
}
else{
off_x = lo_x - CGRectGetWidth(self.frame)/;
} ///off_y
if (lo_y < CGRectGetHeight(self.frame)/) {
off_y = ;
}
else if (lo_y > self.contentSize.height - CGRectGetHeight(self.frame)/){
if (self.contentSize.height <= CGRectGetHeight(self.frame)) {
off_y = ;
}
else{
off_y = self.contentSize.height - CGRectGetHeight(self.frame);
} }
else{
off_y = lo_y - CGRectGetHeight(self.frame)/;
}
[self setContentOffset:CGPointMake(off_x, off_y)];
} #pragma mark - 重置图片
- (void)resetImageViewState{
self.zoomScale = ;
_mainImage = nil;;
self.mainImageView.image = nil; }
#pragma mark - 变量
- (UIImageView *)mainImageView {
if (!_mainImageView) {
_mainImageView = [UIImageView new];
_mainImageView.image = nil;
_mainImageView.contentMode = UIViewContentModeScaleAspectFit;
_mainImageView.userInteractionEnabled = YES;
}
return _mainImageView;
} #pragma mark - 单击
- (void)tapSingleSponse:(UITapGestureRecognizer *)singleTap{
if (!self.mainImageView.image) {
return;
} if (self.zoomScale != ) {
[UIView animateWithDuration:0.2 animations:^{
self.zoomScale = ;
} completion:^(BOOL finished) {
[self setContentOffset:_currPont animated:YES];
}];
}
}
#pragma mark - 双击
- (void)tapDoubleSponse:(UITapGestureRecognizer *)doubleTap{
if (!self.mainImageView.image) {
return;
}
CGPoint point = [doubleTap locationInView:self.mainImageView];
if (self.zoomScale == ) {
[UIView animateWithDuration:0.2 animations:^{
self.zoomScale = 2.0;
[self zoomingOffset:point];
}];
}
else{
[UIView animateWithDuration:0.2 animations:^{
self.zoomScale = ;
} completion:^(BOOL finished) {
[self setContentOffset:_currPont animated:YES];
}];
}
} #pragma mark - UIScrollViewDelegate
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
if (!self.mainImageView.image) {
return;
}
CGRect imageViewFrame = self.mainImageView.frame;
CGFloat width = imageViewFrame.size.width,
height = imageViewFrame.size.height,
sHeight = scrollView.bounds.size.height,
sWidth = scrollView.bounds.size.width;
if (height > sHeight) {
imageViewFrame.origin.y = ;
} else {
imageViewFrame.origin.y = (sHeight - height) / 2.0;
}
if (width > sWidth) {
imageViewFrame.origin.x = ;
} else {
imageViewFrame.origin.x = (sWidth - width) / 2.0;
}
self.mainImageView.frame = imageViewFrame;
} - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.mainImageView;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (self.isZooming || self.zoomScale != ) {
return;
}
_currPont = scrollView.contentOffset; }
#pragma mark - 监听屏幕旋转通知
- (void)statusBarOrientationChange:(NSNotification *)notification{
self.zoomScale = ;
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
} @end

USE

XKZoomingView *zoomView = [[XKZoomingView alloc]init];
zoomView.frame = self.view.bounds;
zoomView.mainImage = [UIImage imageNamed:@""];
[self.view addSubview:zoomView];

ELSE

iOS- XKZoomingView 简单的图片缩放预览,支持横屏、长图【手势:单击、双击、放大缩小】的更多相关文章

  1. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  2. iOS HTML图片本地预览

    引言 相信用过苹果手机的童鞋,会发现很多新闻类的应用,都可以实现HTML图片本地预览,那么这是如何实现的呢?本文将深入阐述其中的原理. 关于此功能,我还实现了一个DEMO,大家可以点击此访问更详细内容 ...

  3. Android图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  4. Azure SQL 数据库的灵活缩放预览版简介

    Eron Kelly SQL Server 产品管理部门产品市场营销总经理 几天前,我们宣布了发布 Azure SQL 数据库的灵活缩放公共预览版.新增的灵活缩放功能通过简化开发和管理,简化了扩展和缩 ...

  5. Android 举例说明自己的定义Camera图片和预览,以及前后摄像头切换

    如何调用本地图片,并调用系统拍摄的图像上一博文解释(http://blog.csdn.net/a123demi/article/details/40003695)的功能. 而本博文将通过实例实现自己定 ...

  6. js实现FileUpload选择图片后预览功能

    当asp.net的FileUpload选择一个图片后不需要上传就能显示出图片的预览功能, 代码: <%@ Page Language="C#" AutoEventWireup ...

  7. 图片本地预览 flash html5

    dataURI 一种能够在页面嵌入外部资源的URI方案.能够降低图片或者样式表的http请求数量,提高效率. ie8把dataURI 的属性值限制在32k以内. 图片本地预览: 由于安全原因,通过fi ...

  8. 巧用weui.gallery(),点击图片后预览图片

    要在页面需要加载的JS文件: <script src="../js/libs/weui.min.js"></script> 可以去weui的文档中下载,这是 ...

  9. node.js平台下,cropper.js实现图片裁剪预览并转换为base64发送至服务端。

    一 .准备工作 1.首先需要先下载cropper,常规使用npm,进入项目路径后执行以下命令: npm install cropper 2. cropper基于jquery,在此不要忘记引入jq,同时 ...

随机推荐

  1. cdnbest独立主控用户如何开通日志分析

    1.cdn独立主控用户开通日志分析,先用授权的帐号在官网平台登陆,然后购买日志套餐 2.在自已的主控平台还要做两步操作: 1.增加个日志套餐,内容随便,因为设置是无效的,只是需要一个套餐 2. 给用户 ...

  2. cdnbest的proxy里api用法案例:

    用户的proxy帐号里api key要设置好,那个key设置后是不显示的,但会显示已设置 key是自已随便生成的 $uid = 22222; $skey = 'langansafe&*#'; ...

  3. CentOS6.8 使man支持显示中文

    1.安装显示中文的man命令 wget https://src.fedoraproject.org/repo/pkgs/man-pages-zh-CN/manpages-zh-1.5.1.tar.gz ...

  4. Polynomial regression

  5. vue去掉地址栏#(带来的后果)

    按以下修改后,带来的后果:打包后部分图片访问不到,首页没加载router-view内容 router 的index中配置模式设置为history export default new Router({ ...

  6. node.js中express框架的基本使用

    express是一个基于node.js平台的,快速,开放,极简的web开发框架. 一.安装 express npm install express --save 二.简单使用 express //引入 ...

  7. Activex、OLE、COM、OCX、DLL之间的区别

    先明确组件(Component)和对象(Object)之间的区别: 组件是一个可重用的模块,它是由一组处理过程.数据封装和用户接口组成的业务对象(Rules Object).组件看起来像对象,但不符合 ...

  8. node.js 调试问题

    最近打算在项目过程中使用node.js辅助解决一些问题,需要用到node.js的调试技术. 通常而言,大家都会提到debugger或者node-inspector方法. debugger方法谁用谁知道 ...

  9. cookie和session 以及Django中应用

    cookie和session 以及Django中应用   cookie和session机制 cookie和session机制 cookie机制采用的是在客户端保持状态的方案.作用就是为了解决HTTP协 ...

  10. Python下安装MySQLdb模块

    ----------------------[针对Windows下python 的MySQLdb模块安装]--------------------- 一.检查MySQLdb模块是否安装,可在DOS命令 ...