欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-19 16:59:10
前言 图片浏览器大家应该都用过,这方面的第三方也有很多,不过有时候第三方会跟我们的需求有一些出入,这就需要我们要么对第三方进行修改要么自己重新定制。我是比较喜欢自己重新定...

前言

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

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];

效果如下:

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

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

总结

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

上一篇:

下一篇: