一: 简介
在项目中免不了会遇到, 实名认证上传身份证绑定银行卡等功能在实际操作中呢, 会涉及到上传图片, 在页面布局时, 可能图片不是一张, 考虑到布局的美观等因素, 显示图片的位置变得很小, 如果想查看上传的图片是否清晰, 内容是否完整, 可能就需要放大才能实现, 下面就和大家分享一下我封装的一类, 完美的实现了图片的缩放功能
另外, 这些博文都是来源于我日常开发中的技术总结, 在时间允许的情况下, 我会针对技术点分别分享 iOSAndroid 两个版本, 尽量附上 demo 以供大家参考, 如果有其他技术点需要, 可在文章后留言, 我会尽全力帮助大家
二: 实现思路分析
给 UIImageView 添加手势
封装一个继承 NSObject 的 FBYImageZoom 类
写一个函数用来接收出入的 UIImageView
根据传入的 UIImageView 重新绘制在 Window 中
添加放大后背景视图的颜色和透明度
使用动画放大展示 ImageView
添加恢复 ImageView 原始尺寸的 tap 点击事件
完成之后将背景视图删掉
三: 实现源码分析
根据实现思路分析, 一步步进行编码实现:
1. 给 UIImageView 添加手势
- self.myImageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 150, SCREEN_WIDTH-100, SCREEN_WIDTH-100)];
- self.myImageView.image = [UIImage imageNamed:@"bankcard"];
- // 添加点击事件
- UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scanBigImageClick:)];
- [_myImageView addGestureRecognizer:tapGestureRecognizer];
- [_myImageView setUserInteractionEnabled:YES];
- [self.view addSubview:_myImageView];
2. 封装一个继承 NSObject 的 FBYImageZoom 类
- #import <Foundation/Foundation.h>
- #import <UIKit/UIKit.h>
- @interface FBYImageZoom : NSObject
- @end
3. 写一个函数用来接收出入的 UIImageView
- /**
- * @param contentImageview 图片所在的 imageView
- */
- +(void)ImageZoomWithImageView:(UIImageView *)contentImageview;
4. 根据传入的 UIImageView 重新绘制在 Window 中
- +(void)ImageZoomWithImageView:(UIImageView *)contentImageview{
- UIWindow *window = [UIApplication sharedApplication].keyWindow;
- [self scanBigImageWithImage:contentImageview.image frame:[contentImageview convertRect:contentImageview.bounds toView:window]];
- }
5. 添加放大后背景视图的颜色和透明度
- // 当前视图
- UIWindow *window = [UIApplication sharedApplication].keyWindow;
- // 背景
- UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
- [backgroundView setBackgroundColor:[UIColor colorWithRed:107/255.0 green:107/255.0 blue:99/255.0 alpha:0.6]];
6. 使用动画放大展示 ImageView
- // 动画放大所展示的 ImageView
- [UIView animateWithDuration: 0.4 animations: ^{
- CGFloat y,
- width,
- height;
- y = ([UIScreen mainScreen].bounds.size.height - image.size.height * [UIScreen mainScreen].bounds.size.width / image.size.width) * 0.5;
- // 宽度为屏幕宽度
- width = [UIScreen mainScreen].bounds.size.width;
- // 高度 根据图片宽高比设置
- height = image.size.height * [UIScreen mainScreen].bounds.size.width / image.size.width; [imageView setFrame: CGRectMake(0, y, width, height)];
- // 重要! 将视图显示出来
- [backgroundView setAlpha: 1];
- }
- completion: ^(BOOL finished) {}];
7. 添加恢复 ImageView 原始尺寸的 tap 点击事件
- // 添加点击事件同样是类方法 -> 作用是再次点击回到初始大小
- UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideImageView:)];
- [backgroundView addGestureRecognizer:tapGestureRecognizer];
- /**
- * 恢复 imageView 原始尺寸
- */
- +(void)hideImageView:(UITapGestureRecognizer *)tap{
- UIView *backgroundView = tap.view;
- // 原始 imageview
- UIImageView *imageView = [tap.view viewWithTag:1024];
- // 恢复
- [UIView animateWithDuration:0.4 animations:^{
- [imageView setFrame:oldframe];
- [backgroundView setAlpha:0];
- } completion:^(BOOL finished) {
- [backgroundView removeFromSuperview];
- }];
- }
8. 完成之后将背景视图删掉
- // 完成后操作 -> 将背景视图删掉
- [backgroundView removeFromSuperview];
四: 项目实际使用
1. 引入封装类 FBYImageZoom
#import "FBYImageZoom.h"
2. 给 UIImageView 添加手势
- // 添加点击事件
- UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scanBigImageClick:)];
3. 调用封装类函数
- // 浏览大图点击事件
- -(void)scanBigImageClick:(UITapGestureRecognizer *)tap{
- NSLog(@"点击图片");
- UIImageView *clickedImageView = (UIImageView *)tap.view;
- [FBYImageZoom ImageZoomWithImageView:clickedImageView];
- }
好了, 到这里点击图片放大到全屏就完成了
4. 长按保存图片
另外就是实现长按保存图片的功能, 这个功能很简单
首先增加长按手势
- // 创建长按手势
- UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(imglongTapClick:)];
- // 添加手势
- [_myImageView addGestureRecognizer:longTap];
然后长按手势弹出警告视图确认
- -(void)imglongTapClick:(UILongPressGestureRecognizer*)gesture
- {
- if(gesture.state==UIGestureRecognizerStateBegan)
- {
- UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"保存图片" message:nil preferredStyle:UIAlertControllerStyleAlert];
- UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
- NSLog(@"取消保存图片");
- }];
- UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
- NSLog(@"确认保存图片");
- // 保存图片到相册
- UIImageWriteToSavedPhotosAlbum(self.myImageView.image,self,@selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:),nil);
- }];
- [alertControl addAction:cancel];
- [alertControl addAction:confirm];
- [self presentViewController:alertControl animated:YES completion:nil];
- }
- }
最后保存图片后的回调
- - (void)imageSavedToPhotosAlbum:(UIImage*)image didFinishSavingWithError: (NSError*)error contextInfo:(id)contextInfo
- {
- NSString *message;
- if(!error) {
- message =@"成功保存到相册";
- UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
- UIAlertAction *action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
- }];
- [alertControl addAction:action];
- [self presentViewController:alertControl animated:YES completion:nil];
- }else
- {
- message = [error description];
- UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
- UIAlertAction *action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
- }];
- [alertControl addAction:action];
- [self presentViewController:alertControl animated:YES completion:nil];
- }
- }
到这里实现点击图片放大和长按保存图片功能就都是实现了, demo 源码已经放在 github 上
五: 项目展示
希望可以帮助大家, 如有问题可加 QQ 技术交流群: 668562416, 如果哪里有什么不对或者不足的地方, 还望读者多多提意见或建议
来源: https://juejin.im/post/5a9df1bdf265da23783fc632