模仿微信九宮格、檢視大圖
由於專案需要封裝了一個九宮格顯示圖片,檢視大圖、選擇多張圖片、可以設定圖片的最大數量、一排最大值、上下左右邊距、圖片的橫向 縱向間距、預設圖片、刪除圖示。話不多說先上圖
Demo地址 [專案連結地址](https://github.com/xiangxianxiao/PicturesListData)
```
//
// ViewController.m
// PicturesListData
//
// Created by Mac on 2018/10/10.
// Copyright © 2018年 xiangxx. All rights reserved.
//
#import "ViewController.h"
#import "XXPicturesCollection.h"
#import "XXImageBrowseViewController.h"
@interface ViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
XXPicturesCollection *pictures;
}
@property (nonatomic, strong) NSMutableArray *addPicturesData;
@property (weak, nonatomic) IBOutlet XXPicturesCollection *addPicturesView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES];
self.addPicturesData = [[NSMutableArray alloc] initWithCapacity:0];
pictures = [[XXPicturesCollection alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 500)];
pictures.configuration.maxRow = 4;
pictures.configuration.maxValue = 6;
pictures.configuration.addImageName = [UIImage imageNamed:@"community_photo"];
pictures.configuration.deleteImageName = [UIImage imageNamed:@"community_close"];
[self.view addSubview:pictures];
__weak typeof(self)weakSelf = self;
pictures.configuration.selectBlock = ^(NSMutableArray *arrayPictures, NSInteger status) {
if (status == -1) {
//新增圖片
weakSelf.addPicturesData = arrayPictures;
[weakSelf photoLibraychoosephoto];
}else{
//點選放大第幾個圖片
XXImageBrowseViewController *imageBro = [[XXImageBrowseViewController alloc] init];
imageBro.imageUrlStringArray = arrayPictures;
imageBro.currentIndex = status;
[weakSelf.navigationController pushViewController:imageBro animated:NO];
}
};
// self.addPicturesView.configuration.addImageName = [UIImage imageNamed:@"community_photo"];
// self.addPicturesView.configuration.deleteImageName = [UIImage imageNamed:@"community_close"];
//
// self.addPicturesView.configuration.maxRow = 4;
// self.addPicturesView.configuration.maxValue = 5;
// __weak typeof(self)weakSelf = self;
// self.addPicturesView.configuration.selectBlock = ^(NSMutableArray *arrayPictures, NSInteger status) {
// if (status == -1) { //新增圖片
// weakSelf.addPicturesData = arrayPictures;
// [weakSelf photoLibraychoosephoto];
// }else{ //點選放大第幾個圖片
// //點選放大第幾個圖片
// XXImageBrowseViewController *imageBro = [[XXImageBrowseViewController alloc] init];
// imageBro.imageUrlStringArray = arrayPictures;
// imageBro.currentIndex = status;
// [weakSelf.navigationController pushViewController:imageBro animated:NO];
// }
// };
}
#pragma mark 呼叫相簿 獲取圖片
-(void)photoLibraychoosephoto{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
//資源型別為圖片庫
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
//設定選擇後的圖片可被編輯
picker.allowsEditing = YES;
picker.navigationBar.translucent = NO;
[self presentViewController:picker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:^{}];
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; //通過key值獲取到圖片
[self.addPicturesData insertObject:image atIndex:0];
// self.addPicturesView.imageArray = self.addPicturesData;
pictures.imageArray = self.addPicturesData;
}
//當用戶取消選擇的時候,呼叫該方法
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:^{}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
```
```
//
// XXPicturesCollection.h
// PicturesListData
//
// Created by Mac on 2018/10/10.
// Copyright © 2018年 xiangxx. All rights reserved.
//
#import <UIKit/UIKit.h>
/**
選擇進行處理操作
@param arrayPictures 相簿陣列資料
@param status 0 新增 1相片放大
*/
typedef void(^SelectPicturesBlock)(NSMutableArray *arrayPictures,NSInteger status);
@class XXPicturesCollection;
@interface XXPicturesCollectionConfiguration : NSObject
@property (nonatomic, copy) SelectPicturesBlock selectBlock;
/**
圖片最大值
*/
@property (nonatomic, assign) NSInteger maxValue;
/**
一排最大值
*/
@property (nonatomic, assign) NSInteger maxRow;
/**
邊距的間距 上邊 左邊 下邊 右邊
*/
@property (nonatomic, assign) NSInteger topMargin;
@property (nonatomic, assign) NSInteger leftMargin;
@property (nonatomic, assign) NSInteger bottomMargin;
@property (nonatomic, assign) NSInteger rightMargin;
/**
圖片橫向間距
*/
@property (nonatomic, assign) NSInteger horizontalSpacing;
/**
圖片豎向間距
*/
@property (nonatomic, assign) NSInteger verticalSpacing;
/**
相關檢視
*/
@property (nonatomic, strong) XXPicturesCollection * picturesCollection;
/**
新增事件的圖片
*/
@property (nonatomic, strong) UIImage *addImageName;
/**
刪除事件的圖片
*/
@property (nonatomic, strong) UIImage *deleteImageName;
@end
@interface XXPicturesCollection : UIView
/**
初始化
@param frame 位置
@param configuration 配置
@return 圖片新增器
*/
- (instancetype)initWithFrame:(CGRect)frame AndConfiguration:(XXPicturesCollectionConfiguration *)configuration;
/**
配置
*/
@property (nonatomic, strong) XXPicturesCollectionConfiguration * configuration;
@property (nonatomic, strong) NSMutableArray *imageArray;
@end
```
//
// XXPicturesCollection.m
// PicturesListData
//
// Created by Mac on 2018/10/10.
// Copyright © 2018年 xiangxx. All rights reserved.
//
#import "XXPicturesCollection.h"
#import "XXPicturesCollectionViewCell.h"
@implementation XXPicturesCollectionConfiguration
- (instancetype)init {
self = [super init];
if (self) {
[self initData];
}
return self;
}
- (void)initData{
self.maxValue = 9;
self.maxRow = 3;
self.topMargin = 10;
self.leftMargin = 10;
self.bottomMargin = 10;
self.rightMargin = 10;
self.horizontalSpacing = 8;
self.verticalSpacing = 8;
self.addImageName = [UIImage imageNamed:@"community_photo"];
self.deleteImageName = [UIImage imageNamed:@"community_close"];
}
- (void)setMaxRow:(NSInteger)maxRow {
_maxRow = maxRow;
self.picturesCollection.configuration = self;
}
- (void)setMaxValue:(NSInteger)maxValue{
_maxValue = maxValue;
self.picturesCollection.configuration = self;
}
- (void)setTopMargin:(NSInteger)topMargin{
_topMargin = topMargin;
self.picturesCollection.configuration = self;
}
- (void)setLeftMargin:(NSInteger)leftMargin{
_leftMargin = leftMargin;
self.picturesCollection.configuration = self;
}
- (void)setBottomMargin:(NSInteger)bottomMargin{
_bottomMargin = bottomMargin;
self.picturesCollection.configuration = self;
}
- (void)setRightMargin:(NSInteger)rightMargin{
_rightMargin = rightMargin;
self.picturesCollection.configuration = self;
}
- (void)setHorizontalSpacing:(NSInteger)horizontalSpacing{
_horizontalSpacing = horizontalSpacing;
self.picturesCollection.configuration = self;
}
- (void)setVerticalSpacing:(NSInteger)verticalSpacing{
_verticalSpacing = verticalSpacing;
self.picturesCollection.configuration = self;
}
- (void)setaddImageName:(UIImage *)addImageName{
_addImageName = addImageName;
self.picturesCollection.configuration = self;
}
- (void)setDeleteImageName:(UIImage *)deleteImageName{
_deleteImageName = deleteImageName;
self.picturesCollection.configuration = self;
}
@end
@interface XXPicturesCollection()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSMutableArray *picturesArray;
@property (nonatomic, assign) NSInteger indexTag;
@end
@implementation XXPicturesCollection
- (instancetype)initWithFrame:(CGRect)frame AndConfiguration:(XXPicturesCollectionConfiguration *)configuration {
if (self = [super initWithFrame:frame]) {
self.configuration = configuration;
self.configuration.picturesCollection = self;
[self initUI];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
self.configuration = [[XXPicturesCollectionConfiguration alloc] init];
self.configuration.picturesCollection = self;
// [self initUI];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.configuration = [[XXPicturesCollectionConfiguration alloc] init];
self.configuration.picturesCollection = self;
// [self initUI];
}
return self;
}
- (instancetype)init {
self = [super init];
if (self) {
self.configuration = [[XXPicturesCollectionConfiguration alloc] init];
self.configuration.picturesCollection = self;
}
return self;
}
#pragma mark - layoutSubviews
- (void)layoutSubviews
{
[super layoutSubviews];
_width = self.frame.size.width;
if (!self.collectionView) {
[self initUI];
}else {
self.collectionView.frame = CGRectMake(0, 0, _width, self.frame.size.height);
}
}
- (void)setConfiguration:(XXPicturesCollectionConfiguration *)configuration {
_configuration = configuration;
[self.collectionView reloadData];
}
- (void)initUI{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, _width, self.frame.size.height) collectionViewLayout:layout];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
self.collectionView.backgroundColor = [UIColor whiteColor];
[self addSubview:self.collectionView];
[self.collectionView registerClass:[XXPicturesCollectionViewCell class] forCellWithReuseIdentifier:@"XXPicturesCollectionViewCell"];
self.picturesArray = [NSMutableArray arrayWithObjects:@"", nil];
self.imageArray = [[NSMutableArray alloc] init];
}
- (void)setImageArray:(NSMutableArray *)imageArray{
_imageArray = imageArray;
if (imageArray.count > 0) {
_picturesArray = _imageArray;
[self.collectionView reloadData];
}
}
#pragma mark - UICollectionDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
if (self.picturesArray.count < _configuration.maxValue) {
return self.picturesArray.count;
}
return _configuration.maxValue;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
XXPicturesCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"XXPicturesCollectionViewCell" forIndexPath:indexPath];
[cell.deleteImage setBackgroundImage:self.configuration.deleteImageName forState:UIControlStateNormal];
[cell.deleteImage addTarget:self action:@selector(deleteAction:) forControlEvents:UIControlEventTouchUpInside];
cell.deleteImage.tag = 10000 + indexPath.row;
if (self.picturesArray.count-1 != self.configuration.maxValue) {
if (self.picturesArray.count -1 == indexPath.row) {
cell.deleteImage.hidden = YES;
self.indexTag = indexPath.row;
cell.imageView.image = self.configuration.addImageName;
[cell.deleteImage setBackgroundImage:self.configuration.deleteImageName forState:UIControlStateNormal];
}else{
cell.deleteImage.hidden = NO;
[cell.imageView setImage:self.picturesArray[indexPath.row]];
}
}else if(self.picturesArray.count-1 == self.configuration.maxValue){
cell.deleteImage.hidden = NO;
[cell.imageView setImage:self.picturesArray[indexPath.row]];
self.indexTag = self.configuration.maxValue;
}
return cell;
}
- (void)deleteAction:(UIButton *)btn{
NSInteger btnTag = btn.tag - 10000;
if (self.picturesArray.count > 1) {
[self.picturesArray removeObjectAtIndex:btnTag];
[self.collectionView reloadData];
}
}
#pragma mark 定義每個UICollectionView的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat widthCollection = (_width - ((_configuration.maxRow-1) * _configuration.horizontalSpacing + _configuration.rightMargin + _configuration.leftMargin))/_configuration.maxRow;
return CGSizeMake(widthCollection, widthCollection);
}
#pragma mark 定義整個CollectionViewCell與整個View的間距
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(_configuration.topMargin, _configuration.leftMargin, _configuration.bottomMargin, _configuration.rightMargin);
}
#pragma mark 定義每個UICollectionView的橫向間距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return _configuration.horizontalSpacing;
}
#pragma mark 定義每個UICollectionView的縱向間距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return _configuration.verticalSpacing;
}
#pragma mark 點選CollectionView觸發事件
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (self.indexTag == indexPath.row) {// 相簿選擇圖片
if (self.configuration.selectBlock) {
self.configuration.selectBlock(self.picturesArray, -1);
}
}else{ // 放大第幾個圖片
if (self.configuration.selectBlock) {
self.configuration.selectBlock(self.picturesArray, indexPath.row);
}
}
}
#pragma mark 設定CollectionViewCell是否可以被點選
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
//#pragma mark - 新增長按手勢
//- (void)setUpLongPressGes {
// UILongPressGestureRecognizer *longPresssGes = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMethod:)];
// [self.collectionView addGestureRecognizer:longPresssGes];
//}
@end
```
#import <UIKit/UIKit.h>
@interface XXPicturesCollectionViewCell : UICollectionViewCell
/**
顯示的圖片
*/
@property (nonatomic, strong) UIImageView *imageView;
/**
刪除圖片
*/
@property (nonatomic, strong) UIButton *deleteImage;
@end
```
```
#import "XXPicturesCollectionViewCell.h"
@implementation XXPicturesCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self.contentView addSubview:self.imageView];
[self.contentView addSubview:self.deleteImage];
}
return self;
}
- (UIImageView *)imageView{
if (!_imageView) {
_imageView = [[UIImageView alloc] init];
_imageView.frame = self.bounds;
_imageView.contentMode = UIViewContentModeScaleAspectFill;
_imageView.clipsToBounds = YES;
}
return _imageView;
}
- (UIButton *)deleteImage{
if (!_deleteImage) {
_deleteImage = [UIButton buttonWithType:UIButtonTypeCustom];
_deleteImage.frame = CGRectMake(_imageView.frame.size.width-10, -5, 15, 15);
}
return _deleteImage;
}
@end
```
```
/**
點選檢視圖片
*/
@interface XXImageBrowseViewController : UIViewController
@property (strong, nonatomic) NSArray *imageUrlStringArray;
@property (nonatomic, copy) NSString *isNetWork;
@property (nonatomic, assign) NSInteger currentIndex;
@end
```
```
#import "XXImageBrowseViewController.h"
#import "EZImageBrowser.h"
#import "EZImageBrowserCell.h"
#import <EZImageBrowserKit/EZImageBrowserKit.h>
#import "UIImageView+WebCache.h"
@interface XXImageBrowseViewController ()<EZImageBrowserDelegate>
@end
@implementation XXImageBrowseViewController
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
EZImageBrowser *browser = [[EZImageBrowser alloc] init];
[browser setDelegate:self];
[browser showWithCurrentIndex:_currentIndex completion:nil];
}
#pragma mark - EZImageBrowserDelegate
- (NSInteger)numberOfCellsInImageBrowser:(EZImageBrowser *)imageBrowser{
return self.imageUrlStringArray.count - 1; // 減去最後的加號圖片
}
- (EZImageBrowserCell *)imageBrowser:(EZImageBrowser *)imageBrowser cellForRowAtIndex:(NSInteger )index{
EZImageBrowserCell *cell = [imageBrowser dequeueReusableCell];
if (!cell) {
cell = [[EZImageBrowserCell alloc] init];
}
if (self.isNetWork){
cell.loadingView.hidden = YES;
[cell.imageView sd_setImageWithURL:[[NSURL alloc] initWithString:self.imageUrlStringArray[index]] placeholderImage:[UIImage imageNamed:@"post_info_z"] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
CGFloat progress = (CGFloat)receivedSize / expectedSize;
[cell.loadingView showAnimateByPropress:progress];
} completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
cell.loadingView.hidden = YES;
}];
}else{
cell.imageView.image = self.imageUrlStringArray[index];
}
return cell;
}
//- (void)imageBrowserWillDisappear:(EZImageBrowser *)imageBrowser{
//
//}
-(void)imageBrowserDidDisappear:(EZImageBrowser *)imageBrowser{
[self.navigationController popViewControllerAnimated:NO];
}
@end
```
#圖片瀏覽器
pod 'EZImageBrowserKit'
pod 'SDWebImage'
Demo地址 [專案連結地址](https://github.com/xiangxianxiao/PicturesListData)