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

 更新时间:2017年12月30日 10:58:06   作者:Abner_G  
最近发现许多常用的APP都有图片浏览器,于是想仿照着自己写一个,下面这篇文章主要给大家介绍了关于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];

效果如下:


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

总结

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

相关文章

  • ios7中UIViewControllerBasedStatusBarAppearance作用详解

    ios7中UIViewControllerBasedStatusBarAppearance作用详解

    这篇文章主要介绍了 ios7中UIViewControllerBasedStatusBarAppearance作用详解的相关资料,需要的朋友可以参考下
    2016-11-11
  • IOS 中UIApplication详解及实例

    IOS 中UIApplication详解及实例

    这篇文章主要介绍了IOS 中UIApplication详解及实例的相关资料,需要的朋友可以参考下
    2017-05-05
  • CocoaPods1.9.0 安装使用教程详解

    CocoaPods1.9.0 安装使用教程详解

    CocoaPods是OS X和iOS下的一个第三类库管理工具,这篇文章主要介绍了CocoaPods1.9.0 安装使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • ios scrollview嵌套tableview同向滑动的示例

    ios scrollview嵌套tableview同向滑动的示例

    本篇文章主要介绍了ios scrollview嵌套tableview同向滑动的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • iOS 二维码扫描和应用跳转

    iOS 二维码扫描和应用跳转

    本文讲解如何使用原生框架实现二维码扫描功能,并且进行扫描后的项目跳转。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03
  • iOS微信支付开发案例

    iOS微信支付开发案例

    这篇文章主要为大家详细介绍了iOS微信支付开发案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • iOS9提示框的正确使用方式

    iOS9提示框的正确使用方式

    这篇文章主要为大家详细介绍了iOS9提示框的正确使用方式,iOS8升级到iOS9的过程,弹出提示框的方式有了很大的改变,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • 阿里数据iOS端启动速度优化心得

    阿里数据iOS端启动速度优化心得

    本篇文章给大家详细分析了阿里数据iOS端启动速度优化的知识点以及心得,对此有兴趣的朋友参考学习下吧。
    2018-02-02
  • iOS实现去除html标签的方法汇总

    iOS实现去除html标签的方法汇总

    相信大家在做网站的时候,经常会遇到去除html标签的问题,下面这篇文章主要给大家总结介绍了关于iOS如何实现去除html标签的一些方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • iOS开发之路--微博“更多”页面

    iOS开发之路--微博“更多”页面

    本文是IOS开发之路系列文章第五篇,主要讲诉了,如何制作微博的更多页面,并附上效果图及源码,需要的朋友可以参考下,希望能有所帮助
    2014-08-08

最新评论