需求
比如,在分享环节中,将分享的链接转换为二维码,保存在相册中。下次,面对面的时候,只要从相册中出示图片,对方扫一扫就可以了。
生成图片
一般图片需要一定的布局,比如二维码,公司的log
,名称,一些说明文字等等。所有这些,可以用一个UIView
容器来表示。那么,接下来的问题是,怎么样将一个UIView
转变为图片呢?
// 将view转换为image
+ (UIImage *)convertViewToImage:(UIView *)view {
UIImage *image = [[UIImage alloc] init];
//UIGraphicsBeginImageContextWithOptions(区域大小, 是否是非透明的, 屏幕密度);
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, [UIScreen mainScreen].scale);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
相册权限
将图片保存到相册,那么就涉及到相册访问。这里就会有权限问题。
在工程的plist
里面添加,比如
<!-- 相册 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>App需要您的同意,才能访问相册</string>
如果这里不添加的话,可能会导致程序崩溃
权限判断
用户是否开了相册权限,怎么判断呢?
我们这里使用PHPhotoLibrary
,所以判断的方法如下:
// 检查相册授权状态
+ (void)checkPhotoAuthorization:(void(^)(BOOL isAuthorized))resultBlock {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
// 如果还没有决定,跳出授权对话框
if (status == PHAuthorizationStatusNotDetermined) {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (resultBlock) {
if (status == PHAuthorizationStatusAuthorized) {
resultBlock(YES);
} else {
resultBlock(NO);
}
}
}];
} else if (status == PHAuthorizationStatusAuthorized) {
if (resultBlock) {
resultBlock(YES);
}
} else {
if (resultBlock) {
resultBlock(NO);
}
}
}
这里要注意的是未决状态
NotDetermined
,这里最好手动调用弹框函数,不然话,设置里面会找不到地方。
保存图片到相册
保存的过程是异步的,所以用到了block
参数;还要注意,结果的处理要在主线程中,因为保存成功后,可能要改变一下界面。
#import <Photos/Photos.h>
// 保存图片到相册
+ (void)saveImageToPhotoLibrary:(UIImage *)image successBlock:(nullable void(^)(void))successBlock failureBlock:(nullable void(^)(NSString *message))failureBlock {
// 参数判断
if (image == nil) {
if (failureBlock) {
failureBlock(@"图片不存在,无法保存到系统相册。");
}
return;
}
// 先检查权限,再保存照片
[KJTImage checkPhotoAuthorization:^(BOOL isAuthorized) {
if (isAuthorized) {
// 保存图片到相册
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromImage:image];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (success) {
if (successBlock) {
successBlock();
}
} else {
if (failureBlock) {
failureBlock(error.localizedDescription);
}
}
});
}];
} else {
if (failureBlock) {
failureBlock(@"请到\"设置->隐私->照片\"中打开权限");
}
}
}];
}
这里使用了最简单的保存方式,保存在了默认的相册中。如果要自定义相册,会麻烦一些。要学一下PHPhotoLibrary提供的其他API的用法。
另外,检查权限函数式异步的,所以调用上面有点别扭。