前言
在我看來袱巨,任何庫存在的意義都是實(shí)際項(xiàng)目中頻繁的用到阁谆,又不想重復(fù)開發(fā),所以封裝好愉老,以方便下個項(xiàng)目或者他人使用场绿。
這個庫也不例外,圖片已經(jīng)是現(xiàn)在每個App中必須的展示方式了嫉入。
效果圖
- 先看效果圖(基本同微信中的一樣焰盗,但是具體實(shí)現(xiàn)的方式肯定是不同的璧尸。),確定是否是自己所需要的效果熬拒,再繼續(xù)看后面的使用方法爷光。
1. 九宮格模式
2. 聊天模式
注:暫且先將這么簡單的cell直接當(dāng)做聊天時的圖片cell,有時間了我會去實(shí)現(xiàn)氣泡的澎粟。
3. 網(wǎng)頁模式
若想直接使用請轉(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ú)的類溃肪。