iOS_“图片浏览选择”功能的编写思路
最近重新開始練習iOS開發,找感覺。
先做個簡單的圖片瀏覽選擇功能。不用管是難還是簡單,先實現一下。
一、步驟概述
包含三個步驟:
- 創建頁面:圖片選擇頁(collectionView),圖片預覽頁
- 處理數據:在頁面間傳遞圖片數據集或者單張圖片,用系統的Photo庫API獲取圖片
- 實現動畫:各個手勢(GestureRecognizer)結合數值的計算
練習重點:
- 各種手勢(GestureRecognizer)的運用
二、具體實現
創建頁面
首先是創建相應的頁面。這個作為最基礎的部分還是在此略過。總共有三個頁面:
- 入口頁
- 選擇頁
- 預覽頁
- 選擇圖片后的入口頁
處理數據
然后是處理圖片數據,在頁面間傳遞圖片數據。
給圖片加上點擊事件,由于UIImageView默認不能交互,所以需要把交互打開:
在入口頁導入系統的<Photos/Photos.h>庫,在圖片的點擊事件響應方法里,調用Photo庫“查看是否有權限”的API:
if (status == PHAuthorizationStatusNotDetermined) {[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {if (status == PHAuthorizationStatusAuthorized) { // 有權限讀取照片[self performLoadPhotoAssets]; // 自定義方法}}]; } else if (status == PHAuthorizationStatusAuthorized) {// 有權限讀取照片[self performLoadPhotoAssets]; // 自定義方法 } 復制代碼當判斷到有權限查看相冊時,則執行獲取圖片的方法[self performLoadPhotoAssets]:
- 先從系統相冊獲取圖片assetsArray
- 然后傳遞到下一個UICollectionView界面
在這個UICollectionView界面,也就是圖片選擇頁,在接口處自然是定義好屬性:
@interface YLPhotoSelectionViewController : UICollectionViewController@property(nonatomic, copy) NSArray * _Nullable assetsArray;@end 復制代碼這個collectionView沒什么好多說的,實現collectionView的dataSource和delegate即可,唯一要注意的是在CollectionViewCell里繼續引入并調用Photo庫解碼PHAseet:
- cell里接受數據的屬性
- 在asset屬性的set里解碼PHAsset
然后接著在collectionView的點擊代理里,把整個圖片數組和被選擇圖片的索引值傳遞給圖片預覽頁:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {NSInteger row = indexPath.row;// 圖片預覽頁YLPhotoPreviewViewController *previewVC = [[YLPhotoPreviewViewController alloc] init];// 傳遞圖片和圖片的索引值previewVC.photoAssetsArray = self.assetsArray;previewVC.photoIndex = row;[self.navigationController pushViewController:previewVC animated:YES]; } 復制代碼傳遞整個圖片數組和被選擇圖片的索引值,而不是只傳遞被選擇的圖片,這樣做目的是給輕掃手勢切換圖片提供相應的數據,通過對索引值的加和減來實現。
同樣地,在圖片預覽頁面的接口定義接收數據的屬性:
@interface YLPhotoPreviewViewController : UIViewController@property(nonatomic, copy) NSArray * _Nullable photoAssetsArray; @property(nonatomic, assign) NSInteger photoIndex;@end 復制代碼圖片的呈現很簡單,一張鋪滿屏幕的UIImageView,同樣用在cell里的Photo庫的解碼方法,把數據賦值給UIImageView,注意這里的圖片是通過傳遞過來的兩個屬性組合取出:
PHAsset *asset = self.photoAssetsArray[self.photoIndex]; 復制代碼實現動畫
最后是這次的重點,實現各種手勢操作:
- 長按,UILongPressGestureRecognizer
- 輕掃,UISwipeGestureRecognizer
- 縮放,UIPinchGestureRecognizer
- 旋轉,UIRotationGestureRecognizer
- 滑動,UIPanGestureRecognizer
- 屏幕邊緣滑動,UIScreenEdgePanGestureRecognizer
這里重點記錄一下縮放、旋轉和平移這三個手勢實現時,都需要有處理的數據,全部代碼在GitHub里。
首先它們都需要記錄一個最終數值:
// 最終照片的比例 @property (assign, nonatomic) CGFloat finalPinchScale; // 最終旋轉角度 @property (assign, nonatomic) CGFloat finalRotaionAngle; // 最終平移的位置 @property (assign, nonatomic) CGPoint finalPanTranslastion; 復制代碼其次都需要記錄上次縮放、旋轉或平移的值:
// 上次縮放的比例 static CGFloat _lastPinchScale = 1; // 上一次旋轉的角度 static CGFloat _lastRotaionAngle = 0; // 上次平移的位置 static CGPoint _lastTranslation = {.x = 0, .y = 0}; 復制代碼然后是根據操作的狀態state來計算數值,以縮放的代碼為例:
if (sender.state == UIGestureRecognizerStateChanged) {// 改變照片的縮放比例self.finalPinchScale = _lastPinchScale * currentPinchScale;// 將finalPinchScaley應用在照片上[self transformForImage]; // 自定義方法} else if (sender.state == UIGestureRecognizerStateEnded) {// 更新lastPinchScale的數值到本次縮放的比例_lastPinchScale = _lastPinchScale *currentPinchScale;} 復制代碼然后就是執行關鍵的自定義方法[self transformForImage]:
- (void)transformForImage {// 把最終值傳入相應的transform類型CGAffineTransform scaleTransform = CGAffineTransformMakeScale(self.finalPinchScale, self.finalPinchScale);CGAffineTransform rotationTransform = CGAffineTransformRotate(scaleTransform, self.finalRotaionAngle);CGAffineTransform translationTransform = CGAffineTransformTranslate(rotationTransform, _finalPanTranslastion.x, _finalPanTranslastion.y);self.previewImageView.transform = translationTransform; } 復制代碼這里是最終的自定義方法,可以看到不同類型的transform是需要疊加在一起,然后最后一個transform類型賦值給視圖的transform屬性。
最后要主要,當有多個容易沖突的手勢操作時,這些手勢需要實現相應的代理方法:
// 縮放、旋轉、平移手勢各自簽署協議 pinchGesture.delegate = self; rotationGesture.delegate = self; panGesture.delegate = self;// “同時生效”的代理方法 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {return YES; } 復制代碼然后就可以操作手勢來實現縮放、旋轉等功能了:
三、總結
iOS開發很大一部分工作是熟悉使用系統提供的強大API,然后做適度的封裝。
至于編程的另一部分——算法,數據結構,編程范式等,不分后端還是前端,都是編程者需要結合理論和實踐不斷提高的東西。
總結
以上是生活随笔為你收集整理的iOS_“图片浏览选择”功能的编写思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【mysql学习-2】
- 下一篇: Spark Stream整合flum和k