#import "XMGSeeBigPictureViewController.h"
#import "XMGTopic.h"
#import <SVProgressHUD.h>
#import <Photos/Photos.h> @interface XMGSeeBigPictureViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIButton *saveButton;
@property (nonatomic, weak) UIScrollView *scrollView;
@property (nonatomic, weak) UIImageView *imageView; /** 当前App对应的自定义相册 */
- (PHAssetCollection *)createdCollection;
/** 返回刚才保存到【相机胶卷】的图片 */
- (PHFetchResult<PHAsset *> *)createdAssets;
@end @implementation XMGSeeBigPictureViewController - (void)viewDidLoad {
[super viewDidLoad]; // scrollView
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = [UIScreen mainScreen].bounds;
[scrollView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(back)]];
[self.view insertSubview:scrollView atIndex:0];
self.scrollView = scrollView; // imageView
UIImageView *imageView = [[UIImageView alloc] init];
[imageView sd_setImageWithURL:[NSURL URLWithString:self.topic.image1] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (!image) return;
self.saveButton.enabled = YES;
}];
imageView.xmg_width = scrollView.xmg_width;
imageView.xmg_height = imageView.xmg_width * self.topic.height / self.topic.width;
imageView.xmg_x = 0;
if (imageView.xmg_height > XMGScreenH) { // 超过一个屏幕
imageView.xmg_y = 0;
scrollView.contentSize = CGSizeMake(0, imageView.xmg_height);
} else {
imageView.xmg_centerY = scrollView.xmg_height * 0.5;
}
[scrollView addSubview:imageView];
self.imageView = imageView; // 图片缩放
CGFloat maxScale = self.topic.width / imageView.xmg_width;
if (maxScale > 1) {
scrollView.maximumZoomScale = maxScale;
scrollView.delegate = self;
}
} #pragma mark - <UIScrollViewDelegate>
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
} #pragma mark - 获得当前App对应的自定义相册
- (PHAssetCollection *)createdCollection
{
// 获得软件名字
NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleNameKey]; // 抓取所有的自定义相册
PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; // 查找当前App对应的自定义相册
for (PHAssetCollection *collection in collections) {
if ([collection.localizedTitle isEqualToString:title]) {
return collection;
}
} /** 当前App对应的自定义相册没有被创建过 **/
// 创建一个【自定义相册】
NSError *error = nil;
__block NSString *createdCollectionID = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
createdCollectionID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier;
} error:&error]; if (error) return nil; // 根据唯一标识获得刚才创建的相册
return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject;
} - (PHFetchResult<PHAsset *> *)createdAssets
{
NSError *error = nil;
__block NSString *assetID = nil; // 保存图片到【相机胶卷】
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
assetID = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier;
} error:&error]; if (error) return nil; // 获取刚才保存的相片
return [PHAsset fetchAssetsWithLocalIdentifiers:@[assetID] options:nil];
} #pragma mark - 监听点击
- (IBAction)back {
[self dismissViewControllerAnimated:YES completion:nil];
} - (IBAction)save {
PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus]; // 请求\检查访问权限 :
// 如果用户还没有做出选择,会自动弹框,用户对弹框做出选择后,才会调用block
// 如果之前已经做过选择,会直接执行block
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if (status == PHAuthorizationStatusDenied) { // 用户拒绝当前App访问相册
if (oldStatus != PHAuthorizationStatusNotDetermined) {
XMGLog(@"提醒用户打开开关")
}
} else if (status == PHAuthorizationStatusAuthorized) { // 用户允许当前App访问相册
[self saveImageIntoAlbum];
} else if (status == PHAuthorizationStatusRestricted) { // 无法访问相册
[SVProgressHUD showErrorWithStatus:@"因系统原因,无法访问相册!"];
}
});
}];
} /**
* 保存图片到相册
*/
- (void)saveImageIntoAlbum
{
// 获得相片
PHFetchResult<PHAsset *> *createdAssets = self.createdAssets;
if (createdAssets == nil) {
[SVProgressHUD showErrorWithStatus:@"保存图片失败!"];
return;
} // 获得相册
PHAssetCollection *createdCollection = self.createdCollection;
if (createdCollection == nil) {
[SVProgressHUD showErrorWithStatus:@"创建或者获取相册失败!"];
return;
} // 添加刚才保存的图片到【自定义相册】
NSError *error = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection];
[request insertAssets:createdAssets atIndexes:[NSIndexSet indexSetWithIndex:0]];
} error:&error]; // 最后的判断
if (error) {
[SVProgressHUD showErrorWithStatus:@"保存图片失败!"];
} else {
[SVProgressHUD showSuccessWithStatus:@"保存图片成功!"];
}
}
@end

ios---photo实现保存图片到自定义相册的更多相关文章

  1. iOS中怎么存储照片到自定义相册

    在市场上主流App中,大多数App都具有存储图片到自己App的相册中.苹果提供的方法只能存储图片到系统相册,下面讲一下怎么实现: 实现思路:  1.对系统相册进行操作的前提必须导入#import &l ...

  2. iOS分段选择器、旅行App、标度尺、对对碰小游戏、自定义相册等源码

    iOS精选源码 企业级开源项目,模仿艺龙旅行App 标签选择器--LeeTagView CSSegmentedControl常用的分段选择器,简单易用! 仿微信左滑删除 IOS左滑返回 输入框 iOS ...

  3. iOS--app自定义相册--创建相簿,存储图片到手机

    我们在APP中点击照片,都会显示出大图,然后在大图的上面会有个保存照片的按钮,照片直接保存到了系统的相册中,但是因为公司产品的需要,让你创建和APP同名的相册保存在里面,那么就对了,可以看下具体的代码 ...

  4. app保存图片到用户相册时闪退解决办法

    在iOS11中,app保存图片到用户相册时必须添加权限使用描述即NSPhotoLibraryAddUsageDescription,否则会闪退. 只需在info.plist—Property List ...

  5. 微信小程序点击保存图片到本地相册——踩坑

    在微信小程序中要保存图片到本地相册,需要获取相册权限. 总之整个功能实现下来需要如下几个小程序的API:wx.getSetting,wx.authorize,wx.openSetting,wx.dow ...

  6. uniapp+nvue实现仿微信/得物相册插件:选择界面 +自定义相册+图片视频过滤

    本篇文章基于uniapp 框架+ nvue,实现了uniapp仿微信/得物相册选择功能实例项目,该插件实例实现了以下功能: 1: 相册过滤 2: 图视频过滤 3: 界面UI定制化 4: 栅格列数定制化 ...

  7. iOS开发UI篇—Quartz2D(自定义UIImageView控件)

    iOS开发UI篇—Quartz2D(自定义UIImageView控件) 一.实现思路 Quartz2D最大的用途在于自定义View(自定义UI控件),当系统的View不能满足我们使用需求的时候,自定义 ...

  8. android自定义相册 支持低端机不内存溢出

    1 之前在网上看的自定义相册很多时候在低端机都会内存溢出开始上代码把 首先我们要拿到图片的所有路径 cursor = context.getContentResolver().query( Media ...

  9. 借助TZImagePickerController三方库理解自定义相册

    借助TZImagePickerController三方库理解自定义相册 1.整体架构分析 整体框架大致可以分为几个部分 <1>工具类-TZImageManager:这个类主要是工作是提供一 ...

随机推荐

  1. Servlet 的面试题

    Servlet运行在Servlet容器中,其生命周期由容器来管理.Servlet的生命周期通过javax.servlet.Servlet接口中的init().service()和destroy()方法 ...

  2. c++ unordered_map 自定义key

    C++11新增了一类散列容器包括unordered_set, unordered_map, unordered_multiset, unordered_multimap, 即之前熟悉的hash_set ...

  3. Excel特殊符号的录入与录入的秘诀

    软键盘就是输入法上的软键盘 右键单击软键盘 右键! 通过code函数得到符号的数字 按住alt键然后输入数字才可以得到符号 注意是在数字键盘  右边数字键盘区域 插入特殊符号 跳转方向的设置 如果超过 ...

  4. Java方法的参数传递是值传递还是引用传递?

    当基本数据类型(Boolean,byte,char,String,int,Long,float,double)作为参数传递时,传递的是实参值的副本,即传的是值,无论在函数中怎么操作这个副本,实参的值是 ...

  5. 013 CephFS文件系统

    一.Ceph文件系统简介 CephFS提供兼容POSIX的文件系统,将其数据和与那数据作为对象那个存储在Ceph中 CephFS依靠MDS节点来协调RADOS集群的访问 元数据服务器 MDS管理元数据 ...

  6. Logback 学习指南 一

    因为项目中用到 SpringBoot,看到官方文档中提及默认的日志实现是 logback,因此就通过阅读手册和结合实践学习了下相关的知识,记录下以备查阅. 1. logback 是什么? logbac ...

  7. vc++调用msscript.ocx解析实现C++与JavaScript脚本交互

    ScriptControl接口 属性名称 类型 备注 AllowUI BOOL 检测是否允许运行用户的接口元素.如果为False,则诸如消息框之类的界面元素不可见. CodeObject Object ...

  8. shopnc 二次开发问题(一)

    1.关于shopnc商品详情页面多规格抢购,价格显示都是显示的抢购价格问题 路径: data/model/groupbuy.model.php 方法:getGroupbuyInfoByGoodsCom ...

  9. Codeforces Round #612 (Div. 2)

    https://codeforces.com/contest/1287/ A - Angry Students 题意:求A后面的P最长连续有几个? 题解:? int n; char s[200005] ...

  10. 现状、趋势如何?——《2019 年度 SaaS 行业【企业愿景】展望 · 总结篇》

    SaaS 行业产业地图和行业规模 看完SaaS的概念介绍,聪明的小伙伴们应该都理解了SaaS到底是个什么东西,但TOB的应用一般会离生活比较远,这里直接上产业地图,让大家对常见的SaaS产品有一个直观 ...