iOS圖片瀏覽庫DSImageBrowse

前言

在我看來袱巨,任何庫存在的意義都是實(shí)際項(xiàng)目中頻繁的用到阁谆,又不想重復(fù)開發(fā),所以封裝好愉老,以方便下個項(xiàng)目或者他人使用场绿。
這個庫也不例外,圖片已經(jīng)是現(xiàn)在每個App中必須的展示方式了嫉入。

效果圖

  • 先看效果圖(基本同微信中的一樣焰盗,但是具體實(shí)現(xiàn)的方式肯定是不同的璧尸。),確定是否是自己所需要的效果熬拒,再繼續(xù)看后面的使用方法爷光。

1. 九宮格模式

九宮格.gif

2. 聊天模式

注:暫且先將這么簡單的cell直接當(dāng)做聊天時的圖片cell,有時間了我會去實(shí)現(xiàn)氣泡的澎粟。
聊天模式.gif

3. 網(wǎng)頁模式

網(wǎng)頁模式.gif

若想直接使用請轉(zhuǎn)github 歡迎star

類的介紹:

DSImagesData


typedef NS_ENUM(NSUInteger, DSImageBadgeType) {
    DSImageBadgeTypeNone = 0,     //    正常圖片
    DSImageBadgeTypeLong,         //    長圖
    DSImageBadgeTypeGIF,          //    GIF
};


/**
 圖片數(shù)據(jù)
 */
@interface DSImageData : NSObject

@property (nonatomic, strong) NSURL *url;                 //圖片URL
@property (nonatomic, assign) int width;                  //圖片寬度
@property (nonatomic, assign) int height;                 //圖片高度
@property (nonatomic, assign) DSImageBadgeType badgeType; //圖片類型 默認(rèn)None

@end

/**
 包含圖片縮略圖蛀序、大圖等所有圖片的數(shù)據(jù)
 */
@interface DSImagesData : NSObject
//縮略圖數(shù)據(jù)
@property (nonatomic, strong) DSImageData *thumbnailImage;
//大圖數(shù)據(jù)  (這個必須要有)
@property (nonatomic, strong) DSImageData *largeImage;
@end

這個類用來存放數(shù)據(jù)模型,DSImageData是圖片元數(shù)據(jù)模型活烙。DSImagesData是一張圖片的縮略圖徐裸,大圖數(shù)據(jù)(后續(xù)若有需要可增加原圖等,現(xiàn)在本人暫時沒有這個需求啸盏,所以只有這2種)

DSImageLayout

/**
 排版布局重贺,在后臺線程操作以提高性能
 */
@interface DSImageLayout : NSObject

/**
 排版布局對象
 @param imagedata 圖片數(shù)據(jù)
 */
- (instancetype)initWithImageData:(NSArray <DSImagesData *>*)imagedata;

/**
 初始化后,一定要調(diào)用該方法進(jìn)行排版
 如果需要修改默認(rèn)參數(shù)回懦,請初始化完修改參數(shù)气笙,再調(diào)用該方法,否則還是使用默認(rèn)數(shù)據(jù)怯晕。
 */
- (void)layout;

//所有圖片數(shù)據(jù)
@property (nonatomic, strong) NSArray<DSImagesData *> *imagesData;

//計(jì)算后單張圖片的大小 (除了單張圖片并且有縮略圖寬高數(shù)據(jù)潜圃,其余情況下均為正方形)
@property (nonatomic, assign, readonly) CGSize imageSize;

//計(jì)算后整個View的高度
@property (nonatomic, assign, readonly) CGFloat imageBrowseHeight;

//整個View寬度 默認(rèn) 屏幕寬度
@property (nonatomic, assign) CGFloat imageBrowseWidth;

//每張圖片的中間的間隔  默認(rèn) 4
@property (nonatomic, assign) CGFloat imagePadding;

//距離頂部距離  默認(rèn) 12
@property (nonatomic, assign) CGFloat topPadding;

//距離底部距離  默認(rèn) 12
@property (nonatomic, assign) CGFloat bottomPadding;

//距離左邊距離  默認(rèn) 12
@property (nonatomic, assign) CGFloat leftPadding;

//距離右邊距離  默認(rèn) 12
@property (nonatomic, assign) CGFloat rightPadding;

//圖片角標(biāo)寬度  默認(rèn) 28
@property (nonatomic, assign) CGFloat imageBadgeWidth;

//圖片角標(biāo)高度  默認(rèn) 18
@property (nonatomic, assign) CGFloat imageBadgeHeight;

@end

這個類用于在拿到圖片數(shù)據(jù)后在后臺線程進(jìn)行排版,因?yàn)樯婕暗綀D片的界面 類似朋友圈這種的性能要進(jìn)行一定的優(yōu)化贫贝,若有你的界面有涉及到圓角圖片應(yīng)該也在這時候在后臺渲染成圓角圖片然后緩存下來秉犹,排版完在把數(shù)據(jù)設(shè)置到cell時,就可以直接用layout對象的中預(yù)先計(jì)算好的寬和高賦值給控件稚晚。

DSThumbnailView

/**
 縮略圖視圖
 */
@interface DSThumbnailView : UIView
//縮略圖
@property (nonatomic, strong) UIImage *image;
//單擊回調(diào)
@property (nonatomic, copy) void (^touchBlock)(DSThumbnailView *view, CGPoint point);
//長按回調(diào)
@property (nonatomic, copy) void (^longPressBlock)(DSThumbnailView *view, CGPoint point);

@end

這個類就是縮略圖View崇堵,里面只有一個UIImage對象。在設(shè)置圖片時是設(shè)置給layer.contents self.layer.contents = (id)image.CGImage;單擊和長按事件通過響應(yīng)鏈來實(shí)現(xiàn)客燕,使用時你并不會接觸這個View鸳劳。

DSImageBrowseView

@protocol DSImageBrowseDelegate;

@interface DSImageBrowseView : UIView

//存放縮略圖
@property (nonatomic, strong) NSArray<DSThumbnailView *> *imageViews;

//代理
@property (nonatomic, weak) id<DSImageBrowseDelegate> delegate;

//布局對象
@property (nonatomic, strong) DSImageLayout *layout;

//長圖片標(biāo)記圖片名稱
@property (nonatomic, strong) NSString *longImageBadgeName;

//GIF圖片標(biāo)記圖片名稱
@property (nonatomic, strong) NSString *gifImageBadgeName;

//默認(rèn)圖片名稱
@property (nonatomic, strong) NSString *defaultImageName;

@end

@protocol DSImageBrowseDelegate <NSObject>

@optional

//點(diǎn)擊圖片
- (void)imageBrowse:(DSImageBrowseView *)imageView didSelectImageAtIndex:(NSInteger)index;
//長按圖片
- (void)imageBrowse:(DSImageBrowseView *)imageView longPressImageAtIndex:(NSInteger)index;

@end

這個類是用來展示縮略圖的容器View,可顯示1- 9張也搓。通常添加在UITableViewCell中來展示赏廓,接著 UITableViewCell遵循DSImageBrowseDelegate代理,用來實(shí)現(xiàn)單擊和長按事件傍妒。

DSImageShowView

typedef NS_ENUM(NSInteger, DSImageShowType) {
    DSImageShowTypeDefault,     ///  默認(rèn)帶page幔摸,最多9張。
    DSImageShowTypeChat,        ///  默認(rèn)不帶page颤练,可以多張既忆,用于聊天內(nèi)容圖片顯示
    DSImageShowtypeWebImage     ///  用于顯示網(wǎng)頁中的圖片
};


@interface DSImageShowView : UIView

//數(shù)據(jù)
@property (nonatomic, readonly) NSArray<DSImageScrollItem *> *items;

//當(dāng)前頁
@property (nonatomic, readonly) NSInteger currentPage;

//是否使用模糊背景 默認(rèn)NO
@property (nonatomic, assign)   BOOL blurEffectBackground;

/**
 沒有拿到圖片坐標(biāo)時,動畫開始的位置和開始大小。
 默認(rèn)((self.width - 100) / 2,self.height - 100) / 2,100,100);
 */
@property (nonatomic, assign)   CGRect fromRect;

// 長按圖片回調(diào)
@property (nonatomic, copy) void (^longPressBlock)(UIImageView *imageView);
/**
 初始化方法

 @param items item數(shù)據(jù)
 @param type 顯示類型
 @return DSImageShowView實(shí)例
 */
- (instancetype)initWithItems:(NSArray <DSImageScrollItem *>*)items type:(DSImageShowType)type;

- (instancetype)init UNAVAILABLE_ATTRIBUTE;
- (instancetype)initWithFrame:(CGRect)frame UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;

// 視圖展示
- (void)presentfromImageView:(UIView *)fromView toContainer:(UIView *)toContainer index:(NSInteger)index animated:(BOOL)animated completion:(void (^)(void))completion;

// 視圖消失
- (void)dismissAnimated:(BOOL)animated completion:(void (^)(void))completion;

// 會調(diào)用 [self dismissAnimated:YES completion:nil];
- (void)dismiss;

// 只有在type == DSImageShowtypeWebImage 情況下才調(diào)用患雇,否則無效跃脊。
- (void)showWebImageIndex:(NSInteger)index;

@end

這個是用于顯示大圖的View,里面包含一個UIScrollView,做為所有圖片的容器苛吱,UIScrollView里面又含有DSImageScrollView, DSImageScrollView做為單獨(dú)一張圖片的容器捧颅,并且做了復(fù)用迅皇。另外在點(diǎn)擊縮略圖時唾糯,調(diào)用presentfromImageView: toContainer: index: animated: completion:這個方法可顯示該視圖坪圾,Container參數(shù)設(shè)置為self.navigationController.view 這個view(UILayoutContainerView)的層級只比導(dǎo)航欄還高笛粘,所以可以蓋住導(dǎo)航欄郎逃,但是不會蓋住狀態(tài)欄葱色,于是我在顯示圖片的時候廊营,將windowlevel設(shè)置為status級別就可以將狀態(tài)欄也蓋住衰齐。還有一個參數(shù)是fromView任斋,這個主要用于做present 和dismiss的動畫效果,以及下拉隱藏這張圖片這個效果耻涛。showWebImageIndex:這個方法用于在顯示網(wǎng)頁圖片時調(diào)用废酷,沒有額外的動畫效果。

DSImageScrollView

@interface DSImageScrollView : UIScrollView

//內(nèi)容視圖
@property (nonatomic, strong) UIView *imageContainerView;
//圖片視圖
@property (nonatomic, strong) YYAnimatedImageView *imageView;
//當(dāng)前頁(預(yù)加載時使用)
@property (nonatomic, assign) NSInteger page;
//傳入的數(shù)據(jù)
@property (nonatomic, strong) DSImageScrollItem *item;
//進(jìn)度條
@property (nonatomic, strong) CAShapeLayer *progressLayer;

- (void)resizeSubviewSize;

@end

這個類是每一張圖片的容器抹缕,用YYAnimatedImageView可以顯示動態(tài)圖片澈蟆。CAShapeLayer用來畫一個簡單的進(jìn)度條。resizeSubviewSize計(jì)算當(dāng)前圖片的frame卓研。

DSImageScrollItem

@interface DSImageScrollItem : NSObject
//縮略圖
@property (nonatomic, readonly) UIImage *thumbImage;
//高圖的時候裁剪保留頂部
@property (nonatomic, readonly) BOOL thumbClippedToTop;

//縮略圖View
@property (nonatomic, strong) UIView *thumbView;

/**
 默認(rèn)為YES.(聊天模式下才去修改)
 當(dāng)前圖片的縮略圖不可見的話趴俘,動畫效果就會不同。
 */
@property (nonatomic, assign) BOOL isVisibleThumbView;

//默認(rèn)為NO.(請?jiān)诰W(wǎng)頁模式下才設(shè)置為YES)
@property (nonatomic, assign) BOOL cancelPan;

//大圖尺寸奏赘,若無則傳0
@property (nonatomic, assign) CGSize largeImageSize;
//大圖url
@property (nonatomic, strong) NSURL *largeImageURL;

這個類是DSImageScrollView的數(shù)據(jù)模型寥闪。isVisibleThumbView這個屬性是在聊天界面時,圖片的縮略圖不一定在當(dāng)前可見cell中磨淌,這樣沒法做present或者dismiss動畫疲憋,圖片動畫應(yīng)該直接淡入淡出,具體使用Demo中有給出梁只。cancelPan這個屬性的存在是因?yàn)镈SImageScrollView中的圖片超過了屏幕高度缚柳,也就是長圖片,這時候DSImageShowView中添加的pan手勢搪锣,不會被識別秋忙,會先識別到DSImageScrollView的滑動。于是我用響應(yīng)鏈和UIScrollView里的pan手勢來做了一點(diǎn)處理构舟。讓長圖在最頂端時灰追,可以先響應(yīng)DSImageShowView中添加的pan手勢,但是顯示網(wǎng)頁圖片不需要這個手勢,所以設(shè)置了這個屬性來禁用监嗜。

DSForceTouchController

@interface DSForceTouchController : UIViewController

//預(yù)覽圖片視圖
@property (nonatomic, strong) YYAnimatedImageView *imageView;
//預(yù)覽圖片數(shù)據(jù)
@property (nonatomic, strong) DSImageScrollItem *item;
//預(yù)覽圖片Rect
@property (nonatomic, assign) CGRect imageRect;
//action 例如@[@"收藏",@"保存"] 不大于4
@property (nonatomic, strong) NSMutableArray *actionTitles;
//action回調(diào)
@property (nonatomic, copy) void (^actionBlock)(NSInteger index);

@end

這個是3Dtouch用于預(yù)覽的控制器谐檀,里面只做了簡單的處理,3DTouch的主要操作還是在要推出這個控制器的控制器中實(shí)現(xiàn)裁奇⊥┾可參照Demo中的實(shí)現(xiàn)。

DSWebImageViewController

/**
 直接調(diào)用這個方法進(jìn)行初始化即可

 @param images 圖片的url數(shù)組 傳NSString類型
 @param currentImage 當(dāng)前圖片的url
 @return 控制器實(shí)例
 */
- (instancetype)initWithImages:(NSArray <NSString *>*)images currentImage:(NSString *)currentImage;

顯示網(wǎng)頁中的圖片只需要調(diào)用這個初始化方法即可刽肠,當(dāng)然也可以自己實(shí)現(xiàn)用上面那些單獨(dú)的類溃肪。

上面這些只是簡單的介紹一下,沒有具體到每個點(diǎn)音五,見諒惫撰。

源碼地址:

github歡迎star

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市躺涝,隨后出現(xiàn)的幾起案子厨钻,更是在濱河造成了極大的恐慌,老刑警劉巖坚嗜,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夯膀,死亡現(xiàn)場離奇詭異,居然都是意外死亡苍蔬,警方通過查閱死者的電腦和手機(jī)诱建,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碟绑,“玉大人俺猿,你說我怎么就攤上這事「裰伲” “怎么了押袍?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抓狭。 經(jīng)常有香客問我伯病,道長,這世上最難降的妖魔是什么否过? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任午笛,我火速辦了婚禮,結(jié)果婚禮上苗桂,老公的妹妹穿的比我還像新娘药磺。我一直安慰自己,他們只是感情好煤伟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布癌佩。 她就那樣靜靜地躺著木缝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪围辙。 梳的紋絲不亂的頭發(fā)上我碟,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天,我揣著相機(jī)與錄音姚建,去河邊找鬼矫俺。 笑死,一個胖子當(dāng)著我的面吹牛掸冤,可吹牛的內(nèi)容都是我干的厘托。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼稿湿,長吁一口氣:“原來是場噩夢啊……” “哼铅匹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饺藤,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤包斑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后策精,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舰始,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年咽袜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枕稀。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡询刹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萎坷,到底是詐尸還是另有隱情凹联,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布哆档,位于F島的核電站蔽挠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瓜浸。R本人自食惡果不足惜澳淑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望插佛。 院中可真熱鬧杠巡,春花似錦、人聲如沸雇寇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嫩海,卻和暖如春冬殃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叁怪。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工造壮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骂束。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓耳璧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親展箱。 傳聞我的和親對象是個殘疾皇子旨枯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容