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, span) UICollectionView * collection;

@property (nonatomic, span) UIPageControl * pageControl;

@property (nonatomic, span) 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];

效果如下:


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

总结

以上是 iOS开发教程之自定制图片浏览器 的全部内容, 来源链接: utcz.com/z/319368.html

回到顶部