首页 > 系统 > iOS > 正文

iOS开发教程之自定制图片浏览器

2020-07-26 02:33:55
字体:
来源:转载
供稿:网友

前言

图片浏览器大家应该都用过,这方面的第三方也有很多,不过有时候第三方会跟我们的需求有一些出入,这就需要我们要么对第三方进行修改要么自己重新定制。我是比较喜欢自己重新定制的,在这给大家简单介绍一下我定制的图片浏览器,算是给大家提供一个思路,可以在此基础上进行修改完善。

实现原理

通过弹出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];

效果如下:


最后,还是希望能够帮助到有需要的朋友们,愿我们能够一起学习进步,在开发的道路上越走越顺利!!!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对武林网的支持。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表