近期公司组织重构项目,又赶上同事离职,他之前负责过的模块的重构就落到了我的头上。这几天整理代码中封装了几个小控件,其中包括图片轮播器。其实之前在github上看到了很多类似的封装控件,但是都不太理想,于是花点时间自己封装了这个小控件,下面我简单介绍一下:
1.实现代码
MYPageView *pageView = [MYPageView pageView];
pageView.frame = CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 200);
[pageView addImageNames:@[@"pic0", @"pic1", @"pic2", @"pic3", @"pic4"] placeholderImageName:@"pic_placeholder" imageType:ImageOfLocal];
[self.view addSubview:pageView];
本来传递图片名称数组用点语法设置pageView.imageNames
,后来改为通过ImageOfLocal
和ImageOfNetwork
区分是本地图片名称还是网络图片名称。
2.其他方法
pageView.isAutoScroll = YES; // 是否自动轮播,默认为NO
pageView.scrollTime = 3; // 轮播间隔时间
pageView.pageCurrentColor = [UIColor orangeColor]; // 当前pageControl圆点颜色
pageView.pageOtherColor = [UIColor blueColor]; // 其他pageControl圆点颜色
pageView.pageCurrentImageName = @"当前pageControl圆点图片名称";
pageView.pageOtherImageName = @"其他pageControl圆点图片名称";
pageView.pageControlFrame = CGRectMake(0, 0, 100, 100); // 修改pageControl的frame
[pageView addView:addView imageNum:0 frame:CGRectMake(0, 0, 100, 100)]; // 在哪张图片上添加可操作控件
3.MYPageView.m
- 初始化控件
#pragma mark - Initialization
+ (instancetype)pageView
{
return [[self alloc] init];
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:self.scrollView];
[self addSubview:self.pageView];
}
return self;
}
#pragma mark - LazyLoad
- (UIScrollView *)scrollView
{
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] init];
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.pagingEnabled = YES;
_scrollView.delegate = self;
}
return _scrollView;
}
- (UIPageControl *)pageView
{
if (!_pageView) {
_pageView = [[UIPageControl alloc] init];
}
return _pageView;
}
- 添加图片名称数组,如果是网络图片名称,这里我们用的是SDWebImage第三方,简单快捷
- (void)addImageNames:(NSArray *)imageNames placeholderImageName:(NSString *)placeholderImageName imageType:(ImageType)imageType
{
_imageNames = imageNames;
[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
for (NSString *imgName in imageNames) {
UIImageView *imgView = [[UIImageView alloc] init];
if (imageType == ImageOfLocal) {
imgView.image = [UIImage imageNamed:imgName];
} else if (imageType == ImageOfNetwork) {
[imgView sd_setImageWithURL:[NSURL URLWithString:imgName] placeholderImage:[UIImage imageNamed:placeholderImageName]];
}
imgView.userInteractionEnabled = YES;
[self.scrollView addSubview:imgView];
}
self.pageView.numberOfPages = imageNames.count;
[self.pageView sizeToFit];
}
- 实现滑动控件,改变pageControl的currentPage,并且设置滑动时定时器停止,滑动结束定时器开始
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
self.pageView.currentPage = (int)(scrollView.contentOffset.x / scrollView.frame.size.width + 0.5);
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (self.isAutoScroll) {
[self stopTimer];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (self.isAutoScroll) {
[self startTimer];
}
}
#pragma mark - TimerControl
- (void)startTimer
{
NSInteger time = (self.scrollTime == 0) ? 2 : self.scrollTime;
self.timer = [NSTimer timerWithTimeInterval:time target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
- (void)nextPage
{
NSInteger page = self.pageView.currentPage + 1;
if (page == self.pageView.numberOfPages) {
page = 0;
}
CGPoint offset = self.scrollView.contentOffset;
offset.x = page * self.scrollView.frame.size.width;
[self.scrollView setContentOffset:offset animated:YES];
}
- (void)stopTimer
{
[self.timer invalidate];
self.timer = nil;
}
- 设置代理的时候添加tap点击手势
最初打算设置- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
来获取点击事件,最后发现当滑动scrollView的时候也会触发该方法,并且会触发两次。所以选择点击手势,并且方便快捷。
- (void)setDelegate:(id<MYPageViewDelegate>)delegate
{
_delegate = delegate;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)];
[self addGestureRecognizer:tap];
}
- (void)tapClick:(UITapGestureRecognizer *)sender {
if ([self.delegate respondsToSelector:@selector(pageView:didSelectNum:)]) {
[self.delegate pageView:self didSelectNum:self.pageView.currentPage];
}
}
4.总结
网络加载图片那里处理的不是特别好,需要添加SDWebImage三方库,对别人的三方框架依赖性太强,如果自己写个网络加载图片的方法感觉太麻烦,并且不适用。感觉这个框架比较适合我自己的项目,并且适用于APP首次运行的新用户引导页,或许日后有时间把该框架再完善一下。