//
// TGSeeBigPicVC.m
//
// Created by targetcloud on 2017/3/14.
// Copyright © 2017年 targetcloud. All rights reserved.
//
#import "TGSeeBigPicVC.h"
#import "TGTopicM.h"
#import <SVProgressHUD.h>
#import <Photos/Photos.h>
@interface TGSeeBigPicVC ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIButton *saveBtn;
@property (nonatomic, weak) UIScrollView *scrollV;
@property (nonatomic, weak) UIImageView *imageV;
/** 当前App对应的自定义相册 */
- (PHAssetCollection *)createdCollection;//声明为了点语法 self.createdCollection
/** 返回刚才保存到【相机胶卷】的图片 */
- (PHFetchResult<PHAsset *> *)createdAssets;//声明为了点语法 self.createdAssets
@end
@implementation TGSeeBigPicVC
- (void)viewDidLoad {
[super viewDidLoad];
// TGLog(@"viewDidLoad %@",NSStringFromCGRect(self.view.bounds))//{{0, 0}, {600, 600}}
UIScrollView *scrollView = [[UIScrollView alloc] init];
// scrollView.backgroundColor = [UIColor blueColor];
scrollView.frame = [UIScreen mainScreen].bounds;//不用self.view.bounds,从XIB出来不准
//如果用self.vew.bounds,那么要加一句 scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 但这里仍然不用,因为后面要根据SV做计算,另外的做法也可以把控件的创建移至懒加载,viewDidLayoutSubviews布局控件位置
// scrollView.frame = self.view.bounds;
// scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[scrollView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(back)]];
[self.view insertSubview:scrollView atIndex:0];//不要挡返回和保存按钮
_scrollV = scrollView;
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;
_saveBtn.enabled = YES;
}];
imageView.width = scrollView.width;
imageView.height = imageView.width * self.topic.height / self.topic.width;
imageView.x = 0;
if (imageView.height > ScreenH) {
imageView.y = 0;
scrollView.contentSize = CGSizeMake(0, imageView.height);
} else {
imageView.centerY = scrollView.height * 0.5;
}
[scrollView addSubview:imageView];
_imageV = imageView;
CGFloat maxScale = self.topic.width / imageView.width;
if (maxScale > 1) {
scrollView.maximumZoomScale = maxScale;
scrollView.delegate = self;
}
// TGLog(@"%zd",scrollView.autoresizingMask)//自己代码加的为0 ,如果是XIB加的为18
}
//-(void) viewDidAppear:(BOOL)animated{
// TGLog(@"viewDidAppear %@",NSStringFromCGRect(self.view.bounds))//{{0, 0}, {414, 736}}
//}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return _imageV;
}
- (PHAssetCollection *)createdCollection{
NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleNameKey];
PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
for (PHAssetCollection *collection in collections) {
if ([collection.localizedTitle isEqualToString:title]) {
return collection;
}
}
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:_imageV.image].placeholderForCreatedAsset.localIdentifier;
} error:&error];
if (error) return nil;
return [PHAsset fetchAssetsWithLocalIdentifiers:@[assetID] options:nil];
}
- (IBAction)back {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)save {
PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus];
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if (status == PHAuthorizationStatusDenied) { // 用户拒绝当前App访问相册
if (oldStatus != PHAuthorizationStatusNotDetermined) {
[SVProgressHUD showErrorWithStatus:@"若要保存图片请允许APP访问你的相册!"];
}
} 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:@"保存图片成功!"];
}
}
/*
[access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
*/
@end
代码思路
1、首先在info.plist加入key NSPhotoLibraryUsageDescription 和在 .m开始处 #import <Photos/Photos.h>
2、调用过程 save -> saveImageIntoAlbum -> self.createdAssets -> self.createdCollection(使用self. 要在interface声明)