创建继承于UIView的类WJImageScrollView,代码实现如下:

WJImageScrollView.h

#import <UIKit/UIKit.h>

/**点击图片block,参数当前图片索引*/
typedef void(^TapImageViewButtonBlock) (NSInteger imageIndex); @interface WJImageScrollView : UIView
/**切换图片的时间间隔,可选,默认3s*/
@property(nonatomic,assign)CGFloat scrollInterval;
/**页面销毁时应该停止定时器,不然无法释放view 类dealloc时调用
[timer invalidate];
timer = nil;
这个方法能解决问题但不明智,有违封装思想,实际使用中优化 */
@property(nonatomic,strong)NSTimer * timer; /**
* 创建轮播器:创建时调用这个方法
*
* @param frame 滚动视图的frame
* @param images 要显示的图片数组
*
* @return 类的对象
*/
+(instancetype)wjImageScrollViewWithFrame:(CGRect)frame
WithImages:(NSArray *)images; /**
*
*
* @param frame 滚动视图的frame
* @param images 要显示的图片数组
*
* @return 类的对象
*/
-(instancetype)initWithFrame:(CGRect)frame
WithIamges:(NSArray *)images; -(void)addTapEventForImageWithBlock:(TapImageViewButtonBlock)block;
@end

WJImageScrollView.m

#import "WJImageScrollView.h"

@interface WJImageScrollView ()<UIScrollViewDelegate>
@property(nonatomic,strong)UIScrollView * mainScrollView; @property(nonatomic,assign)CGFloat widthView; @property(nonatomic,assign)CGFloat hightView; @property(nonatomic,strong)NSArray * imagesNameArray; @property(nonatomic,assign)NSInteger currentPage; @property(nonatomic,assign)UIViewContentMode imageViewcontentModel; @property(nonatomic,strong)UIPageControl * imageViewPageControl; @property(nonatomic,strong)TapImageViewButtonBlock block; @end
@implementation WJImageScrollView +(instancetype)wjImageScrollViewWithFrame:(CGRect)frame
WithImages:(NSArray *)images{ WJImageScrollView * instance = [[WJImageScrollView alloc]
initWithFrame:frame
WithIamges:images];
return instance; } -(instancetype)initWithFrame:(CGRect)frame
WithIamges:(NSArray *)images{ self = [super initWithFrame:frame];
self.translatesAutoresizingMaskIntoConstraints = NO;
if (self) { /**获取滚动视图的宽度*/
_widthView = frame.size.width; /**获取滚动视图的高度*/
_hightView = frame.size.height; _scrollInterval = ; /**当前显示页面*/
_currentPage = ; _imageViewPageControl = UIViewContentModeScaleToFill; self.clipsToBounds = YES; _imagesNameArray = images; /**初始化滚动视图*/
[self addSubview:self.mainScrollView]; /**创建ImageView*/
[self createImageView]; /**添加imageViewPageControl*/
[self addSubview:self.imageViewPageControl]; /**添加timer*/
[self startTimer];
}
return self;
} -(void)addTapEventForImageWithBlock:(TapImageViewButtonBlock)block{
if (self.block == nil) {
if (block != nil) {
self.block = block;
[self initImageViewButton]; }
}
} -(void)initImageViewButton{
for (int i = ; i <= _imagesNameArray.count; i++) { UIButton * imageBtn = [[UIButton alloc] initWithFrame:CGRectMake(_widthView * i, , _widthView, _hightView)];
imageBtn.tag = + i;
[imageBtn addTarget:self action:@selector(imageBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.mainScrollView addSubview:imageBtn];
}
} #pragma mark - 初始化滚动视图 -(UIScrollView *)mainScrollView{
if (!_mainScrollView) {
_mainScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(, , _widthView, _hightView)];
_mainScrollView.contentSize = CGSizeMake(_widthView * _imagesNameArray.count, _hightView);
_mainScrollView.pagingEnabled = YES;
_mainScrollView.showsHorizontalScrollIndicator = NO;
_mainScrollView.showsVerticalScrollIndicator = NO;
_mainScrollView.delegate = self;
_mainScrollView.bounces = NO;
}
return _mainScrollView;
} #pragma mark - 创建UIImageView
-(void)createImageView{ for (int i = ; i <= _imagesNameArray.count; i++) { UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(_widthView * i, , _widthView, _hightView)]; if (i == _imagesNameArray.count) { [self addImageToImageViewWithImageView:imageView WithIndex:]; }else{ [self addImageToImageViewWithImageView:imageView WithIndex:i];
} [self.mainScrollView addSubview:imageView]; }
} #pragma mark - 加载网络图片或者本地图片
-(void)addImageToImageViewWithImageView:(UIImageView *)imageView WithIndex:(NSInteger)index{
[imageView setImage:[UIImage imageNamed:_imagesNameArray[index]]];
} -(void)imageBtnClick:(UIButton *)btn{
if (self.block) {
self.block((btn.tag - ) == self.imagesNameArray.count? :(btn.tag - ));
}
} #pragma mark - 添加PageControl
-(UIPageControl *)imageViewPageControl{
if (!_imageViewPageControl) {
_imageViewPageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(,_hightView - , _widthView, )];
_imageViewPageControl.numberOfPages = _imagesNameArray.count;
_imageViewPageControl.pageIndicatorTintColor = [UIColor whiteColor];
_imageViewPageControl.currentPageIndicatorTintColor = [UIColor redColor];
_imageViewPageControl.currentPage = _currentPage;
}
return _imageViewPageControl;
} -(void)changeOffset{ if (self.mainScrollView.contentOffset.x / _widthView == _imagesNameArray.count ) { self.imageViewPageControl.currentPage = ;
[self.mainScrollView setContentOffset:CGPointMake(, ) animated:NO]; }else{ [self.mainScrollView setContentOffset:CGPointMake(self.mainScrollView.contentOffset.x + _widthView, ) animated:YES]; }
}
#pragma mark - UIScollerView 代理 -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ NSInteger currentPageNum = (self.mainScrollView.contentOffset.x / _widthView) ;
if (self.mainScrollView.contentOffset.x / _widthView == _imagesNameArray.count ) { self.imageViewPageControl.currentPage = ;
[self.mainScrollView setContentOffset:CGPointMake(, ) animated:NO]; }else{ self.imageViewPageControl.currentPage = currentPageNum; } }
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ [self colseTimer];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView{ [self startTimer];
}
#pragma mark --- 开始计时
-(void)startTimer{ if (_timer == nil) {
_timer = [NSTimer scheduledTimerWithTimeInterval:_scrollInterval target:self selector:@selector(changeOffset) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
}
} #pragma mark --- 停止计时
-(void)colseTimer
{
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
} -(void)dealloc{
NSLog(@"WJImageScrollView释放");
}
@end

使用方法

-(void) addWJImageScrollView{

    //获取要显示的位置
CGRect screenFrame = [[UIScreen mainScreen] bounds]; CGRect frame = CGRectMake(, , screenFrame.size.width - , ); NSArray *imageArray = @[@"001.jpg", @"002.jpg", @"003.jpg", @"004.jpg", @"005.jpg"]; //初始化控件
self.imageViewDisplay = [WJImageScrollView wjImageScrollViewWithFrame:frame WithImages:imageArray]; //设定轮播时间
self.imageViewDisplay.scrollInterval = ; //把该视图添加到相应的父视图上
[self.view addSubview:self.imageViewDisplay]; [self.imageViewDisplay addTapEventForImageWithBlock:^(NSInteger imageIndex) {
NSLog(@"点击了------%zd",imageIndex);
}]; }

能解决问题的不好的方法释放view

-(void)dealloc{
NSLog(@"释放");
[self.imageViewDisplay.timer invalidate];
self.imageViewDisplay.timer = nil;
}

iOS-创建UIScrollerView(封装UIScrollerView)的更多相关文章

  1. [官方教程] [ES4封装教程]1.使用 VMware Player 创建适合封装的虚拟机

    [转载处,http://bbs.itiankong.com/] 前言: 首先要明确的一点,系统封装操作的源计算机一般为虚拟计算机(简称虚拟机.VM等),这也是为什么我们要在封装教程的第一章就专门学习虚 ...

  2. iOS蓝牙原生封装,助力智能硬件开发

    代码地址如下:http://www.demodashi.com/demo/12010.html 人工智能自1956年提出以来,一直默默无闻,近年来人工智能的发展得到重视逐渐发展起步,智能硬件.智能手环 ...

  3. 第九节: 利用RemoteScheduler实现Sheduler的远程控制 第八节: Quartz.Net五大构件之SimpleThreadPool及其四种配置方案 第六节: 六类Calander处理六种不同的时间场景 第五节: Quartz.Net五大构件之Trigger的四大触发类 第三节: Quartz.Net五大构件之Scheduler(创建、封装、基本方法等)和Job(创建、关联

    第九节: 利用RemoteScheduler实现Sheduler的远程控制   一. RemoteScheduler远程控制 1. 背景: 在A服务器上部署了一个Scheduler,我们想在B服务器上 ...

  4. iOS 瀑布流封装

    代码地址如下:http://www.demodashi.com/demo/12284.html 一.效果预览 功能描述:WSLWaterFlowLayout 是在继承于UICollectionView ...

  5. android 仿ios 对话框已封装成工具类

    对话框 在android中是一种非经常见的交互提示用户的方式,可是非常多产品狗都叫我们这些做android的仿ios,搞的我们android程序猿非常苦逼,凭什么效果老是仿ios,有没有一点情怀,只是 ...

  6. JS 函数创建、封装、调用

    一.简单函数创建.封装 第三种就是构造函数 function fun(a,b){ this.firstName=a this.lastName=b } var x=new myFun(Jhon,Dav ...

  7. iOS 下如果存在UIScrollerView 使用UIScreenEdgePanGestureRecognizer实现侧滑效果失效的问题

    当你在使用UIScreenEdgePanGestureRecognizer手势实现侧滑的时候,如果后期你导航控制器push出的界面中包含UIScrollerView,这个时候你会发现,侧滑效果无法实现 ...

  8. iOS创建子工程

    实际开发中,我们可能会同时开发好几个端,比如楼主目前开发的家教平台,需要老师端,家长端,助教端三个端.有很多工具方法,或者封装的自定义控件都是可以复用的.我们就可以把公用的代码抽取出去,新建一个工程, ...

  9. iOS创建界面方法的讨论

    以前在入门的时候,找的入门书籍上编写的 demo 都是基于 Storyboards 拖界面的.后来接触公司项目,发现界面都是用纯代码去写复杂的 autoLayout 的.再然后,领导给我发了个 Mas ...

随机推荐

  1. Facade(外观模式或门面模式)

    常用的模式之一. 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 完美地体现了依赖倒转原则和迪米特法则的思想. Facade模式应用场景: 首先 ...

  2. AS5600磁编码器开发记录

    AS5600使用简介--(程序员版) -----------------本文由"智御电子"提供,同时提供范例教程,以便电子爱好者交流学习.---------------- 前言: ...

  3. ruby中的三目操作符和include?操作

    三目操作符:口?口:口 问号前面的是布尔型的判断,true的话执行第二个方块的语句,false的话执行第三个方块的语句例如:value =(nil ? 0 : 1)p value=>1 .inc ...

  4. golang 正则表达式 匹配局域网

    做一个微服务,需要对http头域里的remoteip做访问限制:所有局域网都要鉴权,其中一些特殊ip,如网关地址,直接拒绝,防止公网访问.正则表达式很好的解决了这个,直接贴代码,读者拿来直接改改就能用 ...

  5. 钓鱼 洛谷p1717

    题目描述 话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,VIP999决定请他吃一次“年年大丰收”,为了表示诚意,他还决定亲自去钓鱼,但是,因为还要准备2013NO ...

  6. 使用GC 初始化DG(将备份集复制到目标端再初始化)

    概述 当前环境中有一个GC节点,一套RAC 11.2.0.4的数据库,一个已经使用GC进行在线初始化好的dg环境,需要模拟在远端使用rman备份集进行初始化DG的操作.   恢复环境 当前环境中 已经 ...

  7. Python 列表下标操作

    Python  列表下标操作 引用网址: https://www.jianshu.com/p/a98e935e4d46

  8. React中类定义组件constructor 和super

    刚开始学习React没多久,在老师的教程里看到了类组件的使用示例,但是和资料上有些冲突,而引发了一些疑问: 类组件中到底要不要定义构造函数constructor()? super()里边到底要不要传入 ...

  9. 「知识学习&日常训练」莫队算法(一)(Codeforce Round #340 Div.2 E)

    题意 (CodeForces 617E) 已知一个长度为\(n\)的整数数列\(a[1],a[2],-,a[n]\),给定查询参数\(l,r\),问\([l,r]\)内,有多少连续子段满足异或和等于\ ...

  10. 「专题训练」Machine Schedule(HDU-1150)

    题意 在一个工厂,有两台机器\(A, B\)生产产品.\(A\)机器有\(n\)种工作模式(模式\(0\),模式\(1\)--模式\(n-1\)).\(B\)机器有\(m\)种工作模式(模式\(0\) ...