iOS 之图片拖拽、捏合、双击缩放以及保存到相册

iOS小技能:查看大图浏览器(图片支持滑动切换) 文章目录引言I 、用法1.1 处理查看大图事件II、demo2.1 数据模型2.2 向下滑动触发退出操作。2.3 下载demo源码III、 转场动画3.1 Modal 转场动画3.2 push 转场动画 引言 应用场景: 查看多张大图,比如查看风险商户的证明材料 主要功能:进入查看器之后,可左右滑动查看上/下张,并支持下滑视图退出查看器 I 、用法 1.1 处理查看大图事件 用法一: 采用模型数据进行传递 避免多个数组下标不一致问题 - (void)showImageBrowser 阅读详情

1.图片拖拽,使用UIScrollView就可以实现,上面添加一个UIImageView

2.捏合和双击缩放通过手势实现,难点在于缩放效果的准确定位

3.保存问题比较简单

下面直接上代码:

.h文件:

#import <UIKit/UIKit.h>
#import "AsyncImageView.h"

@interface DetailPopStarView : UIView<UIScrollViewDelegate>
@property (nonatomic) NSString *url;
@property (nonatomic) AsyncImageView *imgView;
@property (nonatomic) CGFloat width;
@property (nonatomic) CGFloat height;
@property (nonatomic) BOOL isTwiceTaping;
@property (nonatomic) BOOL isDoubleTapingForZoom;
@property (nonatomic) CGFloat currentScale;
@property (nonatomic) CGFloat offsetY;
@property (nonatomic) UIScrollView *scrollView;
@property (nonatomic) UIActivityIndicatorView *activityIndicatorView;
@property (nonatomic) CGFloat touchX;
@property (nonatomic) CGFloat touchY;

-(void) draw;
@end

.m文件:

#import "DetailPopStarView.h"
#import "commonFunctions.h"

#define kScreenWidth  320.0
#define kScreenHeight  460.0
#define kMaxZoom 3.0

@implementation DetailPopStarView

@synthesize imgView = _imgView;
@synthesize url = _url;
@synthesize width = _width;
@synthesize height = _height;
@synthesize activityIndicatorView = _activityIndicatorView;
@synthesize isTwiceTaping = _isTwiceTaping;
@synthesize scrollView = _scrollView;
@synthesize currentScale = _currentScale;
@synthesize isDoubleTapingForZoom = _isDoubleTapingForZoom;
@synthesize  touchX = _touchX;
@synthesize  touchY = _touchY;
@synthesize offsetY = _offsetY;


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{

}

- (void) draw{
    self.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    self.backgroundColor = [UIColor blackColor];
    self.alpha = 0.0;

    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
    [self addSubview:_scrollView];
    _scrollView.delegate = self;
    _scrollView.maximumZoomScale = 5.0;
    CGFloat ratio = _width/_height*kScreenHeight/kScreenWidth;
    CGFloat min = MIN(ratio, 1.0);
    _scrollView.minimumZoomScale = min;
    
    CGFloat height = _height /_width * kScreenWidth;
    _imgView = [[AsyncImageView alloc] initWithFrame:CGRectMake(_scrollView.contentOffset.x+100, _scrollView.contentOffset.y+230, 10, 10)];
    [_imgView loadImage:_url];
    
    CGFloat y = (kScreenHeight - height)/2.0;
    _offsetY = 0.0-y;
    _scrollView.contentSize = CGSizeMake(kScreenWidth, height);
    [_scrollView addSubview:_imgView];
    _scrollView.contentOffset = CGPointMake(0, 0.0-y);
    
    [UIView animateWithDuration:0.6
        delay:0.0
        options: UIViewAnimationCurveEaseOut
        animations:^{
            _imgView.frame = CGRectMake(0, 0, kScreenWidth, height);  
            self.alpha = 1.0;
        } 
        completion:^(BOOL finished){
        }
    ];
    
    
    UITapGestureRecognizer *tapImgView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImgViewHandle)];
    tapImgView.numberOfTapsRequired = 1;
    tapImgView.numberOfTouchesRequired = 1;
    [self addGestureRecognizer:tapImgView];
    
    UITapGestureRecognizer *tapImgViewTwice = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImgViewHandleTwice:)];
    tapImgViewTwice.numberOfTapsRequired = 2;
    tapImgViewTwice.numberOfTouchesRequired = 1;
    [self addGestureRecognizer:tapImgViewTwice];
    [tapImgView requireGestureRecognizerToFail:tapImgViewTwice];

    
    
    UITapGestureRecognizer *saveTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(saveTapHandler)];
    UIButton *save = [commonFunctions generateImage:@"save-pic-button.png" hover:@"save-pic-button-hover.png" withX:245 withY:420];
    [save addGestureRecognizer:saveTap];
    [self addSubview:save];
    
    _activityIndicatorView = [commonFunctions generateActivityIndicatorView];
    [self addSubview:_activityIndicatorView];
}

#pragma mark - UIscrollViewDelegate zoom

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
    _currentScale = scale;
    NSLog(@"current scale:%f",scale);
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    return _imgView;
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView{
    //当捏或移动时,需要对center重新定义以达到正确显示未知
    CGFloat xcenter = scrollView.center.x,ycenter = scrollView.center.y;
    NSLog(@"adjust position,x:%f,y:%f",xcenter,ycenter);
    xcenter = scrollView.contentSize.width > scrollView.frame.size.width?scrollView.contentSize.width/2 :xcenter;
    ycenter = scrollView.contentSize.height > scrollView.frame.size.height ?scrollView.contentSize.height/2 : ycenter;
    //双击放大时,图片不能越界,否则会出现空白。因此需要对边界值进行限制。
    if(_isDoubleTapingForZoom){  
        NSLog(@"taping center");
        xcenter = kMaxZoom*(kScreenWidth - _touchX);
        ycenter = kMaxZoom*(kScreenHeight - _touchY);
        if(xcenter > (kMaxZoom - 0.5)*kScreenWidth){//放大后左边超界
            xcenter = (kMaxZoom - 0.5)*kScreenWidth;
        }else if(xcenter <0.5*kScreenWidth){//放大后右边超界
            xcenter = 0.5*kScreenWidth;
        }
        if(ycenter > (kMaxZoom - 0.5)*kScreenHeight){//放大后左边超界
            ycenter = (kMaxZoom - 0.5)*kScreenHeight +_offsetY*kMaxZoom;
        }else if(ycenter <0.5*kScreenHeight){//放大后右边超界
            ycenter = 0.5*kScreenHeight +_offsetY*kMaxZoom;
        }
        NSLog(@"adjust postion sucess, x:%f,y:%f",xcenter,ycenter);        
    }
    [_imgView setCenter:CGPointMake(xcenter, ycenter)];
}
#pragma mark - tap
-(void)tapImgViewHandle{
    NSLog(@"%d",_isTwiceTaping);
    if(_isTwiceTaping){
        return;
    }
    NSLog(@"tap once");
    
    [UIView animateWithDuration:0.6
        delay:0.0
        options: UIViewAnimationCurveEaseOut
        animations:^{
            _imgView.frame = CGRectMake(_scrollView.contentOffset.x+100, _scrollView.contentOffset.y+230, 10, 10);  
            self.alpha = 0.0;
        } 
        completion:^(BOOL finished){
            [self removeFromSuperview];
        }
    ];    
    
}
-(IBAction)tapImgViewHandleTwice:(UIGestureRecognizer *)sender{
    _touchX = [sender locationInView:sender.view].x;
    _touchY = [sender locationInView:sender.view].y;
    if(_isTwiceTaping){
        return;
    }
    _isTwiceTaping = YES;
    
    NSLog(@"tap twice");
    
    if(_currentScale > 1.0){
        _currentScale = 1.0;
        [_scrollView setZoomScale:1.0 animated:YES];
    }else{
        _isDoubleTapingForZoom = YES;
        _currentScale = kMaxZoom;
        [_scrollView setZoomScale:kMaxZoom animated:YES];
    }
    _isDoubleTapingForZoom = NO;
    //延时做标记判断,使用户点击3次时的单击效果不生效。
    [self performSelector:@selector(twiceTaping) withObject:nil afterDelay:0.65];
    NSLog(@"sdfdf");
}
-(void)twiceTaping{
    NSLog(@"no");
    _isTwiceTaping = NO;
}
-(void) saveTapHandler{
    if([_activityIndicatorView isAnimating]){
        return;
    }
    [_activityIndicatorView startAnimating] ;
    UIImageWriteToSavedPhotosAlbum(_imgView.image, self, @selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), nil);
}
#pragma mark - savePhotoAlbumDelegate
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *) contextInfo {  
    NSString *message;  
    NSString *title;  
    
    [_activityIndicatorView stopAnimating];
    if (!error) {
        title = @"恭喜";  
        message = @"成功保存到相册";  
    } else {  
        title = @"失败";  
        message = [error description];  
    }  
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil]; 
    [alert show];
}

@end

【信息科学与工程学】计算机科学与自动化——第六十三篇 人机交互之前端交互参数知识库02 每个分支下又细分了四个关键方向,并按照“研究对象/焦点、基本问题、核心理论/概念、研究方法、应用/目标、前沿/发展”的框架进行阐述,严格遵循了六级编码体系。在最终整合时,应建立唯一的学科分类编码表(例如,用两位数字或“ART”、“MED”、“ECO”等字母前缀),并确保所有下级编码(尺度、层次、类别、子类、具体项)的逻辑一致性。此回答中的编码为示例,实际系统需据此调整。控制过程(前馈、同期、反馈)、全面质量管理(TQM)、平衡计分卡(BSC)定量(调查、实验)、定性(访谈、民族志)、混合方法、大数据。 阅读详情

相关推荐

利用iOS实现系统相册大图浏览功能详解

查看大图是们日常开发中经常会遇到的一个需求,下面这篇文章主要给大家介绍了关于利用iOS实现系统相册大图浏览功能的相关资料,文中给出了详细的示例代码供大家参考学习,需要的朋友们下面来一起看看吧。

iOS学习:调用相机,选择图片上传,带预览功能

 摘要 iOS调用相机,iOS调用相册,保存至应用程序沙盒,高保真压缩图片,并有点击放大预览,再次点击缩回至原大小,带动画效果,附源码下载地址。 Xcode版本4.5.1 类库ios6.0 IOS调用相机 图片预览 图片上传 压缩图片 模拟器添加图片 目录[-] 判断是否支持相机,跳转到相机或相册界面七、保存图片 高保真压缩图片方法八、实现点击图

hxpp777的博客 556

【Java】对接微信转账到零钱接口 Java微信商家转账 apiV3(该踩的雷都踩了)

配置apiv3依赖java代码。

Moonhwa的博客 4317

【原创】iOS图片预览(支持缩放和移动)

1.传入图片 PreViewController.h: #import <UIKit/UIKit.h> @interface PreViewController : UIViewController @property (nonatomic,strong) UIImage *preImage; @end 2.图片加载 PreViewController...

weixin_30657999的博客 563

HFSS仿真的后处理结果,如何根据天线表面的电流密度分布对天线进行优化?

在HFSS仿真中,天线表面的Jsurf​是最直观、最有价值的诊断工具之一。它不仅告诉你天线“能不能工作”,还能告诉你“为什么工作”以及“哪里出了问题”。

degogmy的博客 1156

非标准包 game.rgss3a 的打开方法 | 2023 年实测

生活笔记

陌雨’的博客 1万+

ios 图片拖拽,捏,双击放大缩小,以及保存到相册

图片拖拽,放大缩小原来是可以不用自己写算法的,直接用UIscrollView即可实现。 保存相册就比较简单了。 比较麻烦的地方: 捏,双击等动作形成的放大、缩小效果需要准确定位。 h文件: // // DetailPopStarView.h // Gukw // #import <UIKit/UIKit.h> #import "AsyncIm...

weixin_30544657的博客 247

51单片机-点亮LED和蜂鸣器

ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。ULN2003是大电流驱动陈列,多用于单片机、只能仪表、PLC、数字量输出卡等控制电路中。可直接驱动蜂鸣器、继电器等负载。void delay(u16 i) // i等于1大约10uswhile(i--);//取反,高低电平不断变化,产生脉冲delay(10);// 周期200us。

三日沐水 1126

iOS 图片浏览的放大缩小

功能描述:支持网络和本地gif、jpeg等格式图片的浏览、捏合或双击放大缩小、长按保存到本地相册、获取gif图片的循环次数和时长。 主要部分:创建一个继承于UIScrollView的子类视图WSLPhotoZoom,这个视图需要一个展示图片的UIImageView,然后再结合UIScrollView自带的缩放手势的代理方法来达到缩放效果;最后只需要把这个能缩放的视图放到需要展示图片的视图上

wsl2ls的博客 2088

从零到一:RF-DETR如何通过神经架构搜索重塑实时目标检测的边界

RF-DETR通过创新的权重共享神经架构搜索(NAS)机制,重新定义了实时目标检测的技术边界。这项技术在COCO等基准测试中表现卓越,成为首个AP超过60的实时检测器,同时保持跨领域稳定性和高效推理速度。RF-DETR的动态架构调整能力使其能够适应从嵌入式设备到云端服务器的各种硬件环境,为工业质检、自动驾驶等场景提供灵活解决方案。

weixin_29061531的博客 468

CTP-API开发系列之三:柜台系统简介

综合交易平台(Comprehensive Transaction Platform,CTP)是专门为期货公司开发的一套期货经纪业务管理系统,由交易、风险控制和结算三大系统组成。接下来分享的内容,对于期货公司的负责交易、运维同事会比较熟悉,针对CTP-API接口对接的朋友可以了解一下,在接口之上的系统是怎样的。

码上助君的专栏 6195

JXPhotoBrowser完全指南:打造iOS系统级图片浏览体验的终极方案

JXPhotoBrowser 是一个轻量级、可定制的 iOS 图片/视频浏览器,实现 iOS 系统相册的交互体验。支持缩放、拖拽关闭、自定义转场动画等特性,架构清晰,易于集成和扩展。同时支持 UIKit 和 SwiftUI 两种调用方式,为开发者提供灵活高效的图片浏览解决方案。 ## 为什么选择JXPhotoBrowser? 在iOS应用开发中,图片浏览功能是许多App的核心需求。JXPhot

gitblog_00564的博客 545

51单片机入门指南-基于STC89C52(持续更新)

一、环境介绍 编程IDE: keil5 单片机型号: STC89C51/52 开发板: 普中科技的开发板 完整PDF资源下载地址:https://download.youkuaiyun.com/download/xiaolong1126626497/19785856 二、51单片机开发手册介绍 2.1 前言 51单片机是对所有兼容Intel 8031指令系统的单片机的统称。 该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最.

8797

PYPhotoBrowser核心功能揭秘:支持6种手势与2种布局的终极图片浏览器

PYPhotoBrowser是一款专为iOS开发者打造的终极图片浏览器,提供流畅的图片浏览体验和丰富的交互功能。无论是社交应用中的图片查看器,还是相册类应用的核心组件,它都能满足你的需求,让图片浏览变得简单而高效。 ## 📱 两种灵活布局模式,适应不同场景需求 PYPhotoBrowser提供两种截然不同的布局模式,让你可以根据实际需求灵活选择: ### 1. 流水布局(PYPhotosV

gitblog_00229的博客 620

SAP 系统和银行系统通过 SM2 加密算法进行集成

SM2 是基于椭圆曲线离散对数问题(ECDLP)的一种公钥密码算法。椭圆曲线加密的核心原理,是利用了一个数学难题:在椭圆曲线群上,已知曲线上两点的运算结果,逆向推导出这两个点的具体信息是非常困难的。这样的复杂度使得基于椭圆曲线的密码体制比传统的 RSA 更加难以破解。在 SM2 加密中,公钥和私钥的生成与传统的椭圆曲线加密类似。选择一个椭圆曲线和一个基点 P。使用私钥 d,计算公钥 P’ = d * P。私钥 d 保密,而公钥 P’ 可公开分发,用于加密数据。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1211

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

90DaysOfDevOps Day 40:GitHub 程式碼社交網絡 - 首頁、儲存庫與 Fork/Clone 實戰導覽

本篇文章對應 90DaysOfDevOps 挑戰第 40 天,主題是「程式碼的社交網絡(Social Network for Code)」,以 GitHub 為主體,一併帶出 GitLab、BitBucket 等 Git 代管服務。我們會沿著原文的實作脈絡,從登入後的首頁儀表板、個人 Profile、儲存庫主頁與各功能分頁,一路走到 Fork 與 Clone 的完整動手流程,讀完後你將能獨立把任何

gitblog_00751的博客 378

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

URBMediaFocusViewController vs 主流iOS图片查看器:终极选型对比指南

做 iOS 开发时,图片查看器几乎是每个内容型 App 的标配组件。URBMediaFocusViewController 是一款开源的 iOS 图片查看器,它能将媒体缩略图以 Tweetbot 3 同款物理动画平滑放大到全屏展示,交互手感在同类组件中独树一帜。本文将从动画体验、功能覆盖、集成成本、维护状态四个维度,把 URBMediaFocusViewController 与主流 iOS 图片查

gitblog_00934的博客 1218

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

IDM 激活与试用冻结:IDM Activation Script 完整使用指南

Internet Download Manager(IDM)自带的 30 天试用期一到,功能就进入倒计时。开源项目 IDM Activation Script(简称 IAS)提供的是一套纯脚本方案:通过命令行菜单冻结试用期、重置激活状态或尝试激活 IDM,且官方说明其注册表锁定机制在 IDM 安装官方更新后仍然保留,通常无需重复操作。本文面向第一次接触该项目的用户,讲清楚它是什么、怎么选选项、参数

gitblog_00472的博客 767

#iOS开发笔记#UIImageView实现拖动,放大/缩小,旋转

UIImageView是iOS上最基本的图片显示控件,但默认情况下是不支持拖动,放大缩小等功能的。后来在stackoverflow上查找到一种很简单的方法,加上本人自己的理解,步骤整理如下:

Bryster的专栏 7183

iOS 点击图片放大Demo

创建UIImageView类目 添加一个方法 代码如下: .h #import @interface UIImageView (UIImageViewEx) - (void)addDetailShow; @end .m #define kCoverViewTag           1234 #define

屎壳郎情调-成长日记 2720

Xcode控件使用笔记三:UIScrollView 查看大图、缩放、分页

缩放:用到代理 UIScrollViewDelegate协议 // 创建UIScrollView UIScrollView *scroll = [[UIScrollView alloc] init]; scroll.frame = self.view.bounds; scroll.backgroundColor = [UIColor grayColor]; [s

eagle199012的专栏 857

iOS-OC之相册,可以放大,不能循环查看

#import "ViewController.h"#define kuan [UIScreen mainScreen].bounds.size.width#define gao [UIScreen mainScreen].bounds.size.height@interface ViewController ()<UIScrollViewDelegate>@pr...

weixin_34214500的博客 143

iOS 用UIPanGestureRecognizer实现单手指点击拖动缩放

iOS 用UIPanGestureRecognizer实现单手指点击拖动缩放 图1-2 UIPinchGestureRecognizer捏合手势用来缩放有一定的局限性,为此添加了用UIPanGestureRecognizer拖拽手势来实现缩放,代码的主要部分就是进行scale值的计算,不同象限的操作不同,这里的象限指的数学的象限1-1图示: 图1-2 iOS 手机中的坐标系如图1-3: 图1-3 当我们触发拖动事件时需要以began(sender.state)的点为原点(即屏幕刚刚接收到点击事件

meiyulong518的博客 2072

IOS下,利用捏合手势实现图像缩放和显示

图像的缩放查看,在移动终端上早已不是问题,任何一个人都能够熟练的操作图像的缩放。本文所讲述的重点并不是应用层面上的,而是从编码的角度去自己实现一个图像的缩放应用。作者(就是我自己)最近在做一款APP,其中有一个功能就是抓取PC桌面的图像发送到手机上显示。虽说现在的手机屏幕在慢慢的变大,已经可以达到5.5英寸,但是相比PC显示器的20+英寸,还是显得很小,可以展现的内容也很有限。如果整个PC屏幕显示

shenyi0106的专栏 3878

iOS开发——手势识别器(用手势实现图片旋转和缩小放大)

iOS开发中,除了有关触摸的这组方法来控制用户的手指触控外,还可以用UIGestureRecognize的衍生类来进行判断,方便了开发。 UIGestureRecognize的子类类别有以下几种: UITapGestureRecognizer //轻拍识别器 UIPinchGestureRecognizer //捏合识别器 UIRotationGestureRecognizer ...

weixin_30245867的博客 437

ios 根据手势放大或缩小图片

ios 根据手势放大或缩小图片 当用户需要根据自定义大小图片时,需要提供UIPinchGestureRecognizer来识别用户的手势。具体的步骤: 1、新建xcode工程,选择View-based Application,工程名PhotoPanDemo 2、添加一张图片到Resources目录下,这里的图片命名为feiche.jpg 3、打开PhotoPanDemo

fangjjj的专栏 884
上一篇: iOS 之音乐播放
下一篇: OC运行时编程指南
Shicuf
博客等级 码龄16年 11粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值