iOS开发教程之自定制图片浏览器
程序员文章站
2023-12-19 16:59:10
前言
图片浏览器大家应该都用过,这方面的第三方也有很多,不过有时候第三方会跟我们的需求有一些出入,这就需要我们要么对第三方进行修改要么自己重新定制。我是比较喜欢自己重新定...
前言
图片浏览器大家应该都用过,这方面的第三方也有很多,不过有时候第三方会跟我们的需求有一些出入,这就需要我们要么对第三方进行修改要么自己重新定制。我是比较喜欢自己重新定制的,在这给大家简单介绍一下我定制的图片浏览器,算是给大家提供一个思路,可以在此基础上进行修改完善。
实现原理
通过弹出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];
效果如下:
最后,还是希望能够帮助到有需要的朋友们,愿我们能够一起学习进步,在开发的道路上越走越顺利!!!
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。