如何学习新框架(保存图片到相册)

时间:2022-10-06 06:23:14
一.点击查看大图
1.点击图片或按钮(点击查看大图按钮),modal出来一个控制器,显示大图片
 
2.怎么处理能让点击图片就能查看大图?
     两种方法:1.给图片添加点按手势    
                    2.给图片所在的view上添加 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 
          2.1 添加点按手势
               优点:适用于任何场景下,不受限制
               缺点:代码量大
          
          2.2 给图片所在view添加touchesEnded:方法
               优点:能快速达到点击查看大图效果,代码量小
               缺点:只有当图片所在view和图片一样大的时候,方法才好用,应用场景有限
 
3.怎么快速拿到控制器,来modal?
     能快速拿到的控制器,就是窗口的根控制器
     
4.创建一个控制器,点击图片的时候就把控制器modal出来
     4.1 在控制器上添加一个scrollView,占据全屏
          因为大图片能够上下滚动查看
          
     4.2 scrollView上面还要添加一个UIImageView
          我们需要手动创建UIImageView,然后手动添加到scrollView上
          因为图片尺寸不固定,大图占据全屏,小图居中
 
     4.3 在控制器上添加两个按钮
          一个返回按钮,一个保存图片按钮
 
     4.4 所以,我们创建的控制器应该为UIViewController
 
5.在moadl出来的控制器显示大图片
     5.1 要想在控制器中查看大图,首先要拿到大图,怎么拿?
          5.1.1可以创建一个通知,把图片当做通知参数传递
          5.1.2因为控制器是在图片的uiview中modal出来的,可以用顺传的方法,把模型传递给控制器
               顺传: 1.上一级拿到下一级的控制器   2.在下一级控制器中定义属性接收数据    3.在上一级中给下一级定义的属性赋值
 
     5.2 在查看大图控制器中用代码创建一个UIImageView控件,biang添加到scrollView上面
     
     5.3 判断是否是大图
          5.3.1 是大图,就设置UIImageView的frame从0,0(坐标原点)开始显示
                    宽度等于屏幕宽度,高度就按照宽度的缩放比例进行缩放
          
          5.3.2 不是大图,就设置UIImageView的中心为屏幕的中心
 
 6.显示大图的时候,让大图能够缩放
     6.1如何缩放?
 
          6.1.1 添加捏合手势,使用transform对图片缩放
               优点:适用于任何场景
               缺点:代码比较复杂
 
          6.1.2 使用scrollView的代理方法
               优点:代码相对来说,比较简单
               缺点:只有才能使用
 
     6.2 怎么用scrollView代理.进行缩放
 
          6.2.1 遵守协议,实现代理方法
          6.2.2 在代理方法里面返回需要缩放的view
          6.2.3 在外界设置最大(最小的缩放比例)
 
查看大图并进行缩放源代码
 1 - (void)viewDidLoad {
 2  [super viewDidLoad]; 3 4 UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:_item.image0]; 5 6 UIImageView *imageView = [[UIImageView alloc] init]; 7 _imageView = imageView; 8  [imageView sd_setImageWithURL:[NSURL URLWithString:_item.image1] placeholderImage:image]; 9 CGFloat h = XMGScreenW / _item.width * _item.height; 10 imageView.frame = CGRectMake(0, 0, XMGScreenW, h); 11  [_scroolView addSubview:imageView]; 12 13 if (_item.is_bigPicture) { 14 _scroolView.contentSize = CGSizeMake(0, h); 15 16 if (_item.height > h) { 17 CGFloat scale = _item.height / h; 18 //2.设置缩放比例 19 _scroolView.maximumZoomScale = scale; 20 _scroolView.minimumZoomScale = 1; 21  } 22 } else { 23 imageView.center = CGPointMake(XMGScreenW * 0.5, XMGScreenH * 0.5); 24  } 25 // 缩放 26 //1.设置代理,告诉它哪个View需要做缩放 27 //2.设置缩放比例 28 _scroolView.delegate = self; 29 } 30 #pragma mark - UIScrollViewDelegate 31 // 作用:返回需要做缩放的view 32 // 调用:每次缩放的时候才会调用 33 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 34 { 35 return _imageView; 36 }

 

 
二.保存图片到相册
1.保存图片到相册也有两种方法
     1.1 调用系统方法保存到相册
          优点:简单快捷,两个方法就能实现
          缺点:只能保存到系统相册下,不能保存到自定义的相册下
          注意:监听图片是否保存完成的方法,必须是系统指定的方法,可以跳进保存图片到相册的方法里面查看该方法
     
     1.2 用 Photos框架,自定义相册保存图片
          优点:能把图片保存到指定的相册
          缺点:diamante量大,需要学习新的框架
 
保存到系统相册源代码
 1 // 点击保存调用
 2 - (IBAction)save:(id)sender {
 3     // 保存系统相册
 4  UIImageWriteToSavedPhotosAlbum(_imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 5 } 6 // 询问下用户是否允许当前app访问相册 7 // 监听图片是否保存完成 8 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 9 { 10 if (error) { 11 [SVProgressHUD showErrorWithStatus:@"保存失败"]; 12 } else { 13 [SVProgressHUD showSuccessWithStatus:@"保存成功"]; 14  } 15 }

 

 
2.如何学习一个新的框架
     2.1 首先搞清楚这个框架常用的类
     
     2.2 怎么搞清楚,哪些类常用?
          2.2.1 百度(天朝的度娘太复杂,多变)
          2.2.2 查看官方文档
 
     2.3 怎么能快速定位相关框架的官方文档?
               搜索关键字:   框架名称 + FrameWork Reference
 
    如何学习新框架(保存图片到相册)

 

 

 
 
     2.4 如何学习去使用一个类(方法)?
          按住 option 点击类名 或方法名
           总结:1.如果想了解类,有哪些东西,跳头文件 2.如果想了解怎么使用,用option
                如何学习新框架(保存图片到相册)

 

 
 
3.用 Photos框架,自定义相册保存图片
     3.1 保存图片到相册原理
          3.1.1 创建新的相册
          3.1.2 先把图片保存到系统相册
          3.1.3 把图片从系统相册拷贝到新的相册
 
Photos常用5个类,操作相册
    拥有的时候
    PHPhotoLibrary:相簿:(所有相册集合)
    PHAssetCollection:相册(图片集合)
    PHAsset:图片
 
    创建的时候:
    PHAssetCreationRequest:创建新图片,删除图片,修改图片
    PHAssetCollectionChangeRequest:创建相册,删除相册,修改相册
 
     3.2 如何保存图片到自己的相册?
          使用 Photos框架
     
     3.3 Photos框架保存图片到自己相册步骤
          3.3.1 创建图片请求类(给系统相册创建一张新的图片)
          3.3.2 创建相册请求类(修改相册)
          3.3.3 把图片拷贝到自己相册中
          3.3.4 步骤在类的介绍中有示例
          3.3.5 注意:创建图片和相册请求类必须包装在一个方法里面,这个方法在头文件里面能查看到,这个方法又分为同步和异步两种,一般用异步的
          
     3.4 怎么拷贝到自己的相册?
          3.4.1用相册请求类对象 调用 [assetCollectionChangeRequest addAssets:<#(nonnull id<NSFastEnumeration>)#>] 方法
          3.4.2(nonnull id<NSFastEnumeration>)参数是什么意思?
               表示可以传一个对象,但要遵守 NSFastEnumeration 协议
               遵守这个协议的一般是数组,因为 Enumeration 是遍历的意思,一般数组才能遍历
          3.4.3 不知道参数怎么写,怎么办?
               按住option 点击方法,查看方法介绍,里面有介绍参数怎么写
          3.4.4 以后只要看到这个NSFastEnumeration协议,就可以表示数组
 
4.功能做好后我们还发现两个问题
     4.1 保存前要查看app是否有权限访问相册(如果没授权,就询问用户是否允许访问)
     4.2 每次保存都会创建新的相册
        
5.权限问题解决方案
     5.1每次保存前都先查看app权限,如果允许访问,直接保存
     5.2不允许访问,就提示用户,去设置里面设置权限
     5.3如果没有授权,就弹出权限框,让用户授权
 
权限的四种状态:
  (第一次)PHAuthorizationStatusNotDetermined = 0, 不确定是否允许当前app访问系统相册
     PHAuthorizationStatusRestricted, 家长控制
     PHAuthorizationStatusDenied, (拒绝)不允许当前app访问系统相册
     PHAuthorizationStatusAuthorized (授权)允许当前app访问系统相册
 
6.每次都创建新的相册解决方案
     6.1 保存之前,先查看系统相簿是否存在同名的相册
     6.2 如果存在,就保存到这个相册中
     6.3 不存在,就创建相册保存
 
7. 怎么确定是否存在相册?
     7.1思考:用一个属性来决定相册是否存在可以吗? 不可以,下次启动属性就为空了
     7.2 把属性存到沙盒可以吗?   不可以,如果把app卸载,又重新安装,沙盒也为空,但相册存在
     7.3 最终方案:获取所有相册,查看是否存在同名相册
 
8.怎么获取所有相册?
     8.1 先查看相簿类 是否有这样的方法  找关键字PHAssetCollection相册 发现没有
     8.2 去查看相册类 是否有这样的方法 可能是相册自己管理自己  找到一个方法
           + (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(nullable PHFetchOptions *)options; fetch查找的意思             
     8.3 PHFetchResult这个返回值类型不知道是什么,怎么办?
          点进去看一下,发现
     
    如何学习新框架(保存图片到相册)
 
 
     8.4 参数不会传,可以用option 或者先传空,如果有问题,在回来解决参数问题,如果是枚举参数,一般先传默认值
 
保存到图片到自定义相册源代码
 1 // 点击保存调用
 2 - (IBAction)save:(id)sender {
 3    //查看当前app授权状态
 4     PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; 5 switch (status) { 6 case PHAuthorizationStatusNotDetermined: 7 { // 未授权,弹出授权框 8 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { 9 // 用户选择完毕就会调用—选择允许,直接保存 10 if (status == PHAuthorizationStatusAuthorized) { 11  [self savePhoto]; 12  } 13  }]; 14  选择不允许访问,就不保存 15 break; 16  } 17 case PHAuthorizationStatusAuthorized: 18 { // 授权,就直接保存 19  [self savePhoto]; 20 break; 21  } 22 default: 23 {// 拒绝 告知用户去哪打开授权 24 [SVProgressHUD showInfoWithStatus:@"打开设置 -> 查找百思不得姐 -> 打开照片开关 -> 允许当前app访问系统相册就可以保存图片"]; 25 break; 26  } 27  } 28 } 29 30 // 添加图片到自己相册 31 - (void)savePhoto 32 { 33 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 34 // 1.创建图片请求类(创建系统相册中新的图片)PHAssetCreationRequest 35 // 把图片放在系统相册 36 PHAssetCreationRequest *assetCreationRequest = [PHAssetCreationRequest creationRequestForAssetFromImage:_imageView.image]; 37 38 // 2.创建相册请求类(修改相册)PHAssetCollectionChangeRequest 39 PHAssetCollectionChangeRequest *assetCollectionChangeRequest = nil; 40 41 // 获取之前相册 42 PHAssetCollection *assetCollection = [self fetchAssetCollection:@"百思不得姐"]; 43 44 // 判断是否已有相册 45 if (assetCollection) { 46 // 如果存在已有同名相册 指定这个相册,创建相册请求修改类 47 assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection]; 48 } else { //不存在,创建新的相册 49 assetCollectionChangeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"百思不得姐"]; 50  } 51 // 3.把图片添加到相册中 52 // NSFastEnumeration:以后只要看到这个,就可以表示数组 53 //assetCreationRequest.placeholderForCreatedAsset 图片请求类占位符(相当于一个内存地址) 54 //因为creationRequestForAssetFromImage方法是异步实行的,在这里不能保证 assetCreationRequest有值 55 56  [assetCollectionChangeRequest addAssets:@[assetCreationRequest.placeholderForCreatedAsset]]; 57 58 } completionHandler:^(BOOL success, NSError * _Nullable error) { 59 60 if (success) { 61 [SVProgressHUD showSuccessWithStatus:@"保存成功"]; 62 } else { 63 [SVProgressHUD showErrorWithStatus:@"保存失败"]; 64  } 65 66  }]; 67 } 68 69 // 指定相册名称,获取相册 70 - (PHAssetCollection *)fetchAssetCollection:(NSString *)title 71 { 72 // 获取相簿中所有自定义相册 73 PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; 74  遍历相册,判断是否存在同名的相册 75 for (PHAssetCollection *assetCollection in result) { 76 if ([title isEqualToString:assetCollection.localizedTitle]) { 存在,就返回这个相册 77 return assetCollection; 78  } 79  } 80 return nil; 81 }