展示大图,保存图片到相册(如何学习新的框架)

一.点击查看大图

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 在外界设置最大(最小的缩放比例)

查看大图并进行缩放源代码
- (void)viewDidLoad {
[super viewDidLoad];

UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:_item.image0];

UIImageView *imageView = [[UIImageView alloc] init];
_imageView = imageView;
[imageView sd_setImageWithURL:[NSURL URLWithString:_item.image1] placeholderImage:image];
CGFloat h = XMGScreenW / _item.width * _item.height;
imageView.frame = CGRectMake(0, 0, XMGScreenW, h);
[_scroolView addSubview:imageView];

if (_item.is_bigPicture) {
    _scroolView.contentSize = CGSizeMake(0, h);

    if (_item.height > h) {
        CGFloat scale = _item.height / h;
      //2.设置缩放比例
        _scroolView.maximumZoomScale = scale;
        _scroolView.minimumZoomScale = 1;
    }
} else {
    imageView.center = CGPointMake(XTScreenW * 0.5, XTScreenH * 0.5);
}
// 缩放
    //1.设置代理,告诉它哪个View需要做缩放
    //2.设置缩放比例
_scroolView.delegate = self;
}
#pragma mark - UIScrollViewDelegate
// 作用:返回需要做缩放的view
// 调用:每次缩放的时候才会调用
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return _imageView;
}

二.保存图片到相册

1.保存图片到相册也有两种方法

1.1 调用系统方法保存到相册
优点:简单快捷,两个方法就能实现
缺点:只能保存到系统相册下,不能保存到自定义的相册下
注意:监听图片是否保存完成的方法,必须是系统指定的方法,可以跳进保存图片到相册的方法里面查看该方法

1.2 用 Photos框架,自定义相册保存图片
优点:能把图片保存到指定的相册
缺点:diamante量大,需要学习新的框架

保存到系统相册源代码
// 点击保存调用
- (IBAction)save:(id)sender {
// 保存系统相册
UIImageWriteToSavedPhotosAlbum(_imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
// 询问下用户是否允许当前app访问相册
// 监听图片是否保存完成
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        [SVProgressHUD showErrorWithStatus:@"保存失败"];
    } else {
        [SVProgressHUD showSuccessWithStatus:@"保存成功"];
    }
}

2.如何学习一个新的框架

2.1 首先搞清楚这个框架常用的类

2.2 怎么搞清楚,哪些类常用?
2.2.1 百度(天朝的度娘太复杂,多变)
2.2.2 查看官方文档

2.3 怎么能快速定位相关框架的官方文档?
搜索关键字: 框架名称 + FrameWork Reference

Paste_Image.png

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

Paste_Image.png

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这个返回值类型不知道是什么,怎么办?
点进去看一下,发现

Paste_Image.png

8.4 参数不会传,可以用option 或者先传空,如果有问题,在回来解决参数问题,如果是枚举参数,一般先传默认值

保存到图片到自定义相册源代码
// 点击保存调用
- (IBAction)save:(id)sender {
   //查看当前app授权状态
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
switch (status) {
    case PHAuthorizationStatusNotDetermined:
    { // 未授权,弹出授权框
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
           // 用户选择完毕就会调用—选择允许,直接保存
            if (status == PHAuthorizationStatusAuthorized) {
                [self savePhoto];
            }
        }];
       选择不允许访问,就不保存
        break;
    }
    case PHAuthorizationStatusAuthorized:
    { // 授权,就直接保存
        [self savePhoto];
        break;
    }
    default:
    {// 拒绝   告知用户去哪打开授权
        [SVProgressHUD showInfoWithStatus:@"打开设置 -> 查找百思不得姐 -> 打开照片开关 -> 允许当前app访问系统相册就可以保存图片"];
        break;
    }
}
}

// 添加图片到自己相册
- (void)savePhoto
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    // 1.创建图片请求类(创建系统相册中新的图片)PHAssetCreationRequest
    // 把图片放在系统相册
    PHAssetCreationRequest *assetCreationRequest = [PHAssetCreationRequest creationRequestForAssetFromImage:_imageView.image];

    // 2.创建相册请求类(修改相册)PHAssetCollectionChangeRequest
    PHAssetCollectionChangeRequest *assetCollectionChangeRequest = nil;

    // 获取之前相册
    PHAssetCollection *assetCollection = [self fetchAssetCollection:@"百思不得姐"];

    // 判断是否已有相册
    if (assetCollection) {
        // 如果存在已有同名相册   指定这个相册,创建相册请求修改类
        assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
    } else {  //不存在,创建新的相册
        assetCollectionChangeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"百思不得姐"];
    }
    // 3.把图片添加到相册中
    // NSFastEnumeration:以后只要看到这个,就可以表示数组
    //assetCreationRequest.placeholderForCreatedAsset 图片请求类占位符(相当于一个内存地址)
     //因为creationRequestForAssetFromImage方法是异步实行的,在这里不能保证 assetCreationRequest有值

    [assetCollectionChangeRequest addAssets:@[assetCreationRequest.placeholderForCreatedAsset]];

} completionHandler:^(BOOL success, NSError * _Nullable error) {

    if (success) {
        [SVProgressHUD showSuccessWithStatus:@"保存成功"];
    } else {
        [SVProgressHUD showErrorWithStatus:@"保存失败"];
    }

}];
}
// 指定相册名称,获取相册
- (PHAssetCollection *)fetchAssetCollection:(NSString *)title
{
// 获取相簿中所有自定义相册
PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
遍历相册,判断是否存在同名的相册
for (PHAssetCollection *assetCollection in result) {
    if ([title isEqualToString:assetCollection.localizedTitle]) {  存在,就返回这个相册
        return assetCollection;
    }
}
return nil;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,568评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,612评论 4 59
  • 夜晚是很美好的,因着她的寂静而美 白天式忙碌的,无论是工作的忙碌也好,还是玩乐的忙碌也好,只有到了夜里脑子才更加...
    眼神犀利的猫阅读 265评论 0 0
  • 我是一条咸鱼,一条总妄想着不凡却一直平凡的咸鱼。 我一直认为自己应该是注定成就一番事业的人,然而到目前为止似乎都是...
    咸_鱼_哥阅读 251评论 0 0
  • 2017.09.16 天气:晴朗 心情:喜悦,激动 早起:5:30 早睡:22:50 【学习成长】 今...
    爱笑的玉荣阅读 237评论 0 1