ios---photo实现保存图片到自定义相册
#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实现保存图片到自定义相册的更多相关文章
- iOS中怎么存储照片到自定义相册
在市场上主流App中,大多数App都具有存储图片到自己App的相册中.苹果提供的方法只能存储图片到系统相册,下面讲一下怎么实现: 实现思路: 1.对系统相册进行操作的前提必须导入#import &l ...
- iOS分段选择器、旅行App、标度尺、对对碰小游戏、自定义相册等源码
iOS精选源码 企业级开源项目,模仿艺龙旅行App 标签选择器--LeeTagView CSSegmentedControl常用的分段选择器,简单易用! 仿微信左滑删除 IOS左滑返回 输入框 iOS ...
- iOS--app自定义相册--创建相簿,存储图片到手机
我们在APP中点击照片,都会显示出大图,然后在大图的上面会有个保存照片的按钮,照片直接保存到了系统的相册中,但是因为公司产品的需要,让你创建和APP同名的相册保存在里面,那么就对了,可以看下具体的代码 ...
- app保存图片到用户相册时闪退解决办法
在iOS11中,app保存图片到用户相册时必须添加权限使用描述即NSPhotoLibraryAddUsageDescription,否则会闪退. 只需在info.plist—Property List ...
- 微信小程序点击保存图片到本地相册——踩坑
在微信小程序中要保存图片到本地相册,需要获取相册权限. 总之整个功能实现下来需要如下几个小程序的API:wx.getSetting,wx.authorize,wx.openSetting,wx.dow ...
- uniapp+nvue实现仿微信/得物相册插件:选择界面 +自定义相册+图片视频过滤
本篇文章基于uniapp 框架+ nvue,实现了uniapp仿微信/得物相册选择功能实例项目,该插件实例实现了以下功能: 1: 相册过滤 2: 图视频过滤 3: 界面UI定制化 4: 栅格列数定制化 ...
- iOS开发UI篇—Quartz2D(自定义UIImageView控件)
iOS开发UI篇—Quartz2D(自定义UIImageView控件) 一.实现思路 Quartz2D最大的用途在于自定义View(自定义UI控件),当系统的View不能满足我们使用需求的时候,自定义 ...
- android自定义相册 支持低端机不内存溢出
1 之前在网上看的自定义相册很多时候在低端机都会内存溢出开始上代码把 首先我们要拿到图片的所有路径 cursor = context.getContentResolver().query( Media ...
- 借助TZImagePickerController三方库理解自定义相册
借助TZImagePickerController三方库理解自定义相册 1.整体架构分析 整体框架大致可以分为几个部分 <1>工具类-TZImageManager:这个类主要是工作是提供一 ...
随机推荐
- spring-redis-session 自定义 key 和过期时间
对于分布式应用来说,最开始遇到的问题就是 session 的存储了,解决方案大致有如下几种 使用 spring-session 它可以把 session 存储到你想存储的位置,如 redis,mysq ...
- 关于QT中的隐式共享
网上关于隐式共享的解释很多,在此不再陈述.本文主要是记录一下自己学习隐式共享的坑点: 即:隐式共享只发生在非指针的情况下!!!! 如下代码: QImage image1; QImage image2; ...
- 日期格式化跨年bug,是否与你不期而遇?
2020年来临之前,日期格式化操作也为程序员准备了一个跨年级别的bug,不知你的系统是否遇到? 临近2020年元旦的几天,不少网站出现了类似2020/12/29,2020/12/30,2020/12/ ...
- JavaScript中浅拷贝和深拷贝的区别
JavaScript数据类型 基础数据类型:保存在栈内存中的简单数据段 ,有undefined,boolean,number,string,null 引用数据类型:Array,object,Funct ...
- Spring Boot入门(一)
Spring Boot入门 一.第一个Spring Boot程序 1.导入springBoot 依赖 <parent> <groupId>org.springframework ...
- 信息管理java
代码: package 信息管理;//信1805-1 20183763 凌云 public class ScoreInformation { private String stunumber = &q ...
- k8s的简介以及搭建
一:简介 1.什么是k8s? k8s是一个docker容器管理工具 它是一个全新的基于容器技术的分布式架构领先方案,是开源的容器集群管理系统. 在docker的基础上,为容器化的应用提供部署运行,资源 ...
- SpringBoot 2.X集成 jdbc自动配置原理探究
前言 Springboot对于数据访问层,不管是 SQL还是 NOSQL,Spring Boot 底层都是采用 Spring Data 的方式统一处理.Spring Data 是 Spring 家族中 ...
- 【转】C#中base关键字的几种用法:base()
转:https://blog.csdn.net/cplvfx/article/details/82982862 base其实最大的使用地方在面相对象开发的多态性上,base可以完成创建派生类实例时调用 ...
- 深入理解协程(二):yield from实现异步协程
原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的第二篇. yield from ...