当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS开发教程之自定制图片浏览器

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

前言

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

实现原理

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

效果如下:


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

总结

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网