iOS開源照片瀏覽器框架SGPhotoBrowser的設計與實現

發表於2016-07-30

簡介

近日在製作一個開源加密相簿時附帶著設計了一個照片瀏覽器,在進一步優化後釋出到了GitHub供大家使用,該框架雖然沒有MWPhotoBrowser那麼強大,但是使用起來更為方便,操作更符合常規相簿習慣,自定義和修改原始碼也十分簡單。
本文主要介紹這個照片瀏覽器框架的技術要點,如果要深入研究和使用,可以在下面的連結中下載原始碼。

如果你對這個框架有興趣,可以點選這裡前去GitHub下載原始碼,歡迎Star與指出不足

效果圖

縮圖預覽,點選縮圖進入原圖瀏覽,點選底部工具欄可以進入編輯模式。

112376201-d94d124252fa113e

批量匯出與刪除,通過底部工具欄操作。

122376201-2dee4bd3274595f3

檢視原圖,單擊可以隱藏導航欄和工具欄,支援雙擊切換縮放狀態、捏和手勢以及左右滑動切圖。

132376201-e92756a176bb1214

功能與特點

  • block資料來源
    照片瀏覽器的資料來源是通過block回撥的,通過實現相應的block並且提供資料模型即可完成圖片顯示。
  • 記憶體優化
    高解析度的圖片在讀入到記憶體後的記憶體佔用是十分可觀的,因此在點選縮圖進入原圖瀏覽後,由於要左右滑動來檢視其它圖片的原圖,因此至少載入三張原圖(不考慮邊緣情況),分別是當前檢視的圖片和與之相鄰的圖片,而其他圖片則先載入縮圖,在滾動到那些圖片時才去載入原圖以及與之相鄰的原圖,並且替換遠處的原圖為縮圖。
  • 滾動優化
    在滾動完全結束後才去載入原圖並替換縮圖,以防止滾動時卡頓。
  • 同時支援本地與網路圖片
    通過URL的型別來判斷圖片是否來自網路,如果來自網路則非同步下載並顯示進度,同時進行快取。
  • 原圖瀏覽時支援常見的手勢
    原圖瀏覽器時支援單擊隱藏和顯示導航欄和工具條,雙擊在適應螢幕和原始尺寸之間切換,捏和手勢可以縮放圖片,左右滑動可以切換圖片。
  • 支援批量匯出與刪除照片
    可以通過工具欄進入編輯模式來批量處理圖片的匯出與刪除。

技術要點

概述

照片瀏覽器框架依賴了SDWebImage和MBProgressHUD,前者用於處理圖片的非同步下載與快取,後者用於顯示圖片下載的進度。用於縮圖顯示的是collectionView,檢視原圖時每一張圖片都被均勻排列在scrollView上,每一張圖片也被包裹了一個scrollView用於處理縮放。

block資料來源

使用代理模式回撥資料來源會使得程式碼較為分散,因此本框架使用了block來回撥,在SGPhotoBrowser中有四個資料來源block,通過實現他們並且提供相應的資料即可完成圖片顯示,這四個block如下面程式碼所示。

每個照片通過一個SGPhotoModel資料模型類要描述,其中包含了photoURL與thumbURL,分別代表原圖和縮圖的URL,通過URL是否是fileURL來決定是否要非同步下載快取。
block資料來源在縮圖瀏覽時被collectionView的dataSource所呼叫,在原圖瀏覽時被呼叫以獲取特定位置的圖片URL或進行刪除照片後的資料重新整理。

記憶體優化

在檢視原圖時,載入當前位置和與其相鄰位置的原圖,其他位置均載入縮圖,在滑動過程中,動態的切換原圖的載入位置並將原來位置的原圖替換為縮圖,以保證記憶體中最多有三張原圖被載入以節省記憶體,具體實現程式碼如下。

滾動優化

在scrollView的滾動效果尚未停止時進行耗時操作會造成卡頓,為了避免這種情況,可以在scrollView減速完畢後再進行耗時操作。在本框架中,在左右滑動切換圖片時,如果立即載入原圖,會造成卡頓,因此在scrollView減速完畢後才將縮圖替換為原圖,具體實現如下。

本地圖片與網路圖片的處理

所有的圖片都是通過URL進行設定,通過為UIImageView新增分類,並新增方法sg_setImageWithURL:model:方法,傳入當前要載入的圖片的URL以及照片模型,在方法內,通過URL型別來判斷是否要進行非同步下載和快取,在非同步下載時,使用MBProgressHUD來指示進度,具體程式碼如下。

原圖瀏覽時的手勢處理

每張圖片使用一個scrollView包裹來處理捏合手勢縮放,同時通過touchesEnded::方法來判斷單擊和雙擊,由於雙擊時會經過單擊狀態,這裡將單擊事件滯後0.2s處理,如果在這期間觸發了雙擊,則取消單擊事件的處理,實現如下。

圖片的批量處理

在照片的資料模型SGPhotoModel上有一個isSelected屬性來判斷當前圖片是否被選中,通過collectionView的代理方法didUnhighlightItemAtIndexPath:來處理圖片的選中與反選,為了統一點選事件,將點選縮圖進入原圖瀏覽模式的程式碼也放到了這裡,通過是否是編輯模式來區分,編輯模式由於和工具欄直接相關,因此被記錄在工具欄中,具體實現程式碼如下。

更多技術細節可以在GitHub上的原始碼中檢視,點選這裡前去GitHub下載原始碼,歡迎Star和指出不足。

相關文章