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. Pandas聚合

    数据聚合 import pandas as pd from pandas import Series import numpy as np # 准备数据 df = pd.DataFrame([[-0. ...

  2. Python+Selenium学习--cookie处理

    场景 有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie 的测试是无法通过白盒和集成测试完成的.webdriver 可以读取.添加和删除cookie 信息.webdrive ...

  3. [leetcode]70. Climbing Stairs爬楼梯

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  4. centos6 下erlang安装

    https://packages.erlang-solutions.com/erlang/

  5. Swift MD5加密

    很多时候我们会用到md5加密,下面是swift 3.0的实现方法: 首先新建桥接文件 xx-Bridging-Header,方法很多,这里就不介绍了. 然后在桥接文件中引入加密库 #import &l ...

  6. Entity Framework - PostgresQL CodeFirst

    经过几年的更新及业界对Entity Framework 的认同. 现在 EF 可以支持的数据库越来越多了.而PostgresQL 数据库现在也可以使用code first的方式来创建数据库了. 不多说 ...

  7. centos 7 命令行模式和桌面版之间的切换

    CentOS7图形界面与命令行界面切换 在图形界面使用 ctrl+alt+F2切换到dos界面 dos界面 ctrl+alt+F2切换回图形界面 在命令上 输入 init 命令 切换到dos界面 输入 ...

  8. dom4j 操作总结

    在官网https://dom4j.github.io/下载最新的dom4j的jar包,以及配合xpath解析的http://central.maven.org/maven2/jaxen/jaxen/1 ...

  9. 探索未知种族之osg类生物---呼吸分解之渲染遍历二

    那么今天我们就正式进入osg整个呼吸动作之中最复杂的一个动作,ViewerBase::renderingTraversals(),我们先介绍renderingTraversals的开头的简单的几步操作 ...

  10. java中date日期格式的各种转换

    示例 Date dt =new Date(); System.out.println(dt); //格式: Wed Jul 06 09:28:19 CST 2016 //格式:2016-7-6 Str ...