时间:2021-05-01 09:31:59 | 栏目:iOS代码 | 点击:次
前言
图片浏览器大家应该都用过,这方面的第三方也有很多,不过有时候第三方会跟我们的需求有一些出入,这就需要我们要么对第三方进行修改要么自己重新定制。我是比较喜欢自己重新定制的,在这给大家简单介绍一下我定制的图片浏览器,算是给大家提供一个思路,可以在此基础上进行修改完善。
实现原理
通过弹出UIViewController的形式来展示图片,使用UICollectionView并添加手势来实现图片浏览时图片的间隔。
首先创建一个继承于UIViewController的控制器,来作为图片浏览器的控制器,并实现相应的代码如下:
示例代码
#import <UIKit/UIKit.h> #import "RHPhotoBrowser.h" @interface RHPhotoBrowserController : UIViewController - (instancetype)initWithType:(RHPhotoSourceType)type imageArr:(NSArray *)imageArr selectIndex:(NSInteger)selectIndex; @end
#import "RHPhotoBrowserController.h" #import "RHPhotoBrowserCell.h" #define Cell_PhotoBrowser @"Cell_PhotoBrowser" #define PhotoSpace 10 // 图片间距 @interface RHPhotoBrowserController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> @property (nonatomic, strong) UICollectionView * collection; @property (nonatomic, strong) UIPageControl * pageControl; @property (nonatomic, strong) NSMutableArray * dataArr; @property (nonatomic, assign) RHPhotoSourceType type; @property (nonatomic, assign) NSInteger selectIndex; @property (nonatomic, assign) CGFloat panCenterX; @property (nonatomic, assign) CGFloat startOffsetX; @property (nonatomic, assign) CGFloat offsetX; @property (nonatomic, assign) CGFloat panX; @end @implementation RHPhotoBrowserController - (instancetype)initWithType:(RHPhotoSourceType)type imageArr:(NSArray *)imageArr selectIndex:(NSInteger)selectIndex { self = [super init]; if (self) { [self.dataArr removeAllObjects]; [self.dataArr addObjectsFromArray:imageArr]; _type = type; _selectIndex = selectIndex; } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self addSubviews]; [self makeConstraintsForUI]; } #pragma mark - add subviews - (void)addSubviews { self.view.backgroundColor = [UIColor blackColor]; [self.view addSubview:self.collection]; [self.view addSubview:self.pageControl]; } - (void)makeConstraintsForUI { [_collection mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.right.bottom.mas_equalTo(0); }]; [_pageControl mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(0); make.bottom.mas_equalTo(-SS(50)); make.height.mas_equalTo(20); }]; [self performSelector:@selector(setCollectionContentOffset) withObject:nil afterDelay:0.1]; } - (void)setCollectionContentOffset { RHWeakSelf; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.collection setContentOffset:CGPointMake((Screen_Width + PhotoSpace) * _selectIndex, 0) animated:NO]; weakSelf.pageControl.numberOfPages = weakSelf.dataArr.count; weakSelf.pageControl.currentPage = _selectIndex; }); _startOffsetX = _collection.contentOffset.x; } #pragma mark - GestureRecognizer event - (void)panCollection:(UIPanGestureRecognizer *)pan { _panCenterX = [pan translationInView:self.collection].x; if (pan.state == UIGestureRecognizerStateBegan) { _startOffsetX = _collection.contentOffset.x; _offsetX = 0; _panX = 0; } if (_selectIndex == 0) { if (_panCenterX > 0) { CGFloat s = (Screen_Width - _panCenterX) / Screen_Width; _offsetX += (_panCenterX - _panX) * s; _panX = _panCenterX; [self.collection setContentOffset:CGPointMake(-_offsetX, 0) animated:NO]; } else { if (self.dataArr.count == 1) { CGFloat s = (Screen_Width + _panCenterX) / Screen_Width; _offsetX += (_panCenterX - _panX) * s; _panX = _panCenterX; [self.collection setContentOffset:CGPointMake(-_offsetX, 0) animated:NO]; } else { [self.collection setContentOffset:CGPointMake(_startOffsetX - _panCenterX, 0) animated:NO]; } } } else if (_selectIndex == self.dataArr.count - 1) { if (_panCenterX < 0) { CGFloat s = (Screen_Width + _panCenterX) / Screen_Width; _offsetX += (_panCenterX - _panX) * s; _panX = _panCenterX; [self.collection setContentOffset:CGPointMake(_startOffsetX - _offsetX, 0) animated:NO]; } else { [self.collection setContentOffset:CGPointMake(_startOffsetX - _panCenterX, 0) animated:NO]; } } else { [self.collection setContentOffset:CGPointMake(_startOffsetX - _panCenterX, 0) animated:NO]; } if (pan.state == UIGestureRecognizerStateEnded) { if ([self absoluteValue:_panCenterX] > Screen_Width/3) { if (_panCenterX < 0) { _selectIndex += 1; } else { _selectIndex -= 1; } if (_selectIndex == self.dataArr.count) { _selectIndex = self.dataArr.count - 1; } else if (_selectIndex == -1) { _selectIndex = 0; } [self.collection setContentOffset:CGPointMake((Screen_Width + PhotoSpace) * _selectIndex, 0) animated:YES]; self.pageControl.currentPage = _selectIndex; } else { [self.collection setContentOffset:CGPointMake(_startOffsetX, 0) animated:YES]; } } } - (void)swipeCollection:(UISwipeGestureRecognizer *)swipe { if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) { _selectIndex += 1; } else if (swipe.direction == UISwipeGestureRecognizerDirectionRight) { _selectIndex -= 1; } if (_selectIndex == self.dataArr.count) { _selectIndex = self.dataArr.count - 1; } else if (_selectIndex == -1) { _selectIndex = 0; } self.pageControl.currentPage = _selectIndex; [self.collection setContentOffset:CGPointMake((Screen_Width + PhotoSpace) * _selectIndex, 0) animated:YES]; } // 返回value的绝对值 - (CGFloat)absoluteValue:(CGFloat)value { if (value < 0) { return -value; } return value; } #pragma mark - collection delegate - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.dataArr.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { RHPhotoBrowserCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:Cell_PhotoBrowser forIndexPath:indexPath]; if (indexPath.row < self.dataArr.count) { if (_type == RHPhotoSourceTypeImage) { UIImage * image = [self.dataArr objectAtIndex:indexPath.row]; [cell configCellWithImage:image]; } else if (_type == RHPhotoSourceTypeUrl) { NSString * url = [self.dataArr objectAtIndex:indexPath.row]; [cell configCellWithUrl:url]; } else if (_type == RHPhotoSourceTypeFilePath) { NSString * filePath = [self.dataArr objectAtIndex:indexPath.row]; [cell configCellWithFilePath:filePath]; } else if (_type == RHPhotoSourceTypeFileName) { NSString * fileName = [self.dataArr objectAtIndex:indexPath.row]; [cell configCellWithFileName:fileName]; } } return cell; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(Screen_Width, Screen_Height); } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { return PhotoSpace; } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { return 0; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - setter and getter - (UICollectionView *)collection { if (!_collection) { UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init]; layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; UICollectionView * cv = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; cv.backgroundColor = [UIColor blackColor]; cv.delegate = self; cv.dataSource = self; cv.showsHorizontalScrollIndicator = NO; [cv registerClass:[RHPhotoBrowserCell class] forCellWithReuseIdentifier:Cell_PhotoBrowser]; UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panCollection:)]; [cv addGestureRecognizer:pan]; UISwipeGestureRecognizer * swipeL = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeCollection:)]; swipeL.direction = UISwipeGestureRecognizerDirectionLeft; [cv addGestureRecognizer:swipeL]; UISwipeGestureRecognizer * swipeR = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeCollection:)]; swipeR.direction = UISwipeGestureRecognizerDirectionRight; [cv addGestureRecognizer:swipeR]; _collection = cv; } return _collection; } - (UIPageControl *)pageControl { if (!_pageControl) { UIPageControl * pageControl = [[UIPageControl alloc] init]; pageControl.pageIndicatorTintColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.9]; pageControl.currentPageIndicatorTintColor = [UIColor whiteColor]; pageControl.userInteractionEnabled = NO; _pageControl = pageControl; } return _pageControl; } - (NSMutableArray *)dataArr { if (!_dataArr) { _dataArr = [NSMutableArray array]; } return _dataArr; } @end
其实到此基本已经结束了,大家实现一个相对应的cell就可以了。使用时直接通过外漏的方法创建该控制器对象并弹出该控制器即可。
为了更加方便的调用,我又增加了一个NSObject的类来控制以上控制器的调用。如下:
#import <Foundation/Foundation.h> typedef NS_ENUM(NSUInteger, RHPhotoSourceType) { RHPhotoSourceTypeImage = 0, RHPhotoSourceTypeUrl = 1, RHPhotoSourceTypeFilePath = 2, RHPhotoSourceTypeFileName = 3 }; @interface RHPhotoBrowser : NSObject + (RHPhotoBrowser *)shared; - (void)browseImageWithType:(RHPhotoSourceType)type imageArr:(NSArray *)imageArr selectIndex:(NSInteger)selectIndex; @end
#import "RHPhotoBrowser.h" #import "RHPhotoBrowserController.h" @implementation RHPhotoBrowser + (RHPhotoBrowser *)shared { static RHPhotoBrowser * helper = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ helper = [[RHPhotoBrowser alloc] init]; }); return helper; } - (void)browseImageWithType:(RHPhotoSourceType)type imageArr:(NSArray *)imageArr selectIndex:(NSInteger)selectIndex { if (selectIndex > imageArr.count - 1) { selectIndex = 0; } UIViewController * rootVC = [UIApplication sharedApplication].delegate.window.rootViewController; RHPhotoBrowserController * browser = [[RHPhotoBrowserController alloc] initWithType:type imageArr:imageArr selectIndex:selectIndex]; [rootVC presentViewController:browser animated:YES completion:nil]; } @end
这样使用的时候只需要使用该类就可以了。这里大家可以将单例去掉,将对象方法直接改为类方法即可。我是习惯了,所以这样写了。
再给大家看一下使用方法一步调用:
[[RHPhotoBrowser shared] browseImageWithType:RHPhotoSourceTypeFileName imageArr:@[@"c006", @"c007", @"c008", @"c009", @"c010"] selectIndex:2];
效果如下:
最后,还是希望能够帮助到有需要的朋友们,愿我们能够一起学习进步,在开发的道路上越走越顺利!!!
总结