展示大圖,保存圖片到相冊(如何學習新的框架)

一.點擊查看大圖

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;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,811評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,180評論 4 61
  • 夜晚是很美好的,因著她的寂靜而美 白天式忙碌的,無論是工作的忙碌也好,還是玩樂的忙碌也好,只有到了夜里腦子才更加...
    眼神犀利的貓閱讀 286評論 0 0
  • 我是一條咸魚,一條總妄想著不凡卻一直平凡的咸魚。 我一直認為自己應該是注定成就一番事業的人,然而到目前為止似乎都是...
    咸_魚_哥閱讀 296評論 0 0
  • 2017.09.16 天氣:晴朗 心情:喜悅,激動 早起:5:30 早睡:22:50 【學習成長】 今...
    愛笑的玉榮閱讀 275評論 0 1