iOS开发学习--纯代码 UIScrollView 无限循环的实现——代码类封装

时间:2023-04-28 22:12:32

一个简单的利用UIScrollView 实现的无线滚动banner,下面的代码实现,因为封装问题,对两个及一下的view 支持出了一点问题(view是传参进来的,不可以生成两份),但是原理是正确的,智者见智吧

先说一下原理,看下面的图

第一种原理       , 本文是用的原理

为了方便看懂,这里做了2张动图

iOS开发学习--纯代码  UIScrollView 无限循环的实现——代码类封装

iOS开发学习--纯代码  UIScrollView 无限循环的实现——代码类封装

下面是解析图

iOS开发学习--纯代码  UIScrollView 无限循环的实现——代码类封装

第二种原理

iOS开发学习--纯代码  UIScrollView 无限循环的实现——代码类封装

原理清晰了,代码附上,有问题可以留言,会尽快回复,

.h文件

 //
// MyUIScrollView.h
// UIscrollView
//
// Created by Ibokan on 15/8/25.
// Copyright (c) 2015年 Crazy凡. All rights reserved.
// #import <UIKit/UIKit.h> @interface MyUIScrollView : NSObject
@property (nonatomic,strong)UIScrollView *scrollView; //滚动框
@property (nonatomic,strong)UILabel * label;//titlelabel,要想显示图片title 需要先将label 贴到view中,并且settitle,如果不调用settitle 方法,则不会显示
@property (nonatomic,strong)UIPageControl * pageControl;//显示小点
//以上三个控件都需要调用 [self.view addSubView:]方法,否则不会显示
@property BOOL isCarousel;//是否有动画 默认有 View 数量为一张 会关闭动画
@property double delay;//动画播放速度 默认1.5 最小应 > 0.2
- (instancetype)initWithFrame:(CGRect)frame ViewNum:(int)num Margin:(int)margin;//frame是全部尺寸,num是View数量,margin是内容和外边框距离
- (instancetype)initWithFrame:(CGRect)frame ViewNum:(int)num MarginV:(int)marginV MarginH:(int)marginH;//垂直和水平边距
- (instancetype)initWithFrame:(CGRect)frame ViewNum:(int)num MarginT:(int)marginTop MarginR:(int)marginRight MarginB:(int)marginBottom MarginL:(int)marginLeft;//上右下左边距
- (void)setSubView:(NSArray *)viewArray;//填充view,最好多于2个,数量为2的请复制成4个,数量为1的将不允许滑动,2个以上的不需要做特殊处理
- (void)setTitle:(NSArray *)title;
@end

.m 文件

 //
// MyUIScrollView.m
// UIscrollView
//
// Created by Ibokan on 15/8/25.
// Copyright (c) 2015年 Crazy凡. All rights reserved.
// #import "MyUIScrollView.h" @interface MyUIScrollView () <UIScrollViewDelegate>
@property (nonatomic,strong)NSTimer * timer;
@property (nonatomic,strong)NSMutableArray *labeltitle;
@property (nonatomic,strong)NSMutableArray *viewArray;
@property (nonatomic,strong)NSMutableArray *titleArray;
@property int indexc;
@property BOOL isOne; //记录图片是否只有一张
@end @implementation MyUIScrollView
- (instancetype)initWithFrame:(CGRect)frame ViewNum:(int)num Margin:(int)margin
{
[self makeWF:frame VN:num MT:margin MR:margin MB:margin ML:margin];
return self;
}
- (instancetype)initWithFrame:(CGRect)frame ViewNum:(int)num MarginV:(int)marginV MarginH:(int)marginH
{
[self makeWF:frame VN:num MT:marginV MR:marginH MB:marginV ML:marginH];
return self;
}
- (instancetype)initWithFrame:(CGRect)frame ViewNum:(int)num MarginT:(int)marginTop MarginR:(int)marginRight MarginB:(int)marginBottom MarginL:(int)marginLeft;
{
[self makeWF:frame VN:num MT:marginTop MR:marginRight MB:marginBottom ML:marginLeft];
return self;
}
- (void) makeWF:(CGRect)frame VN:(int)num MT:(int)marginT MR:(int)marginR MB:(int)marginB ML:(int)marginL
{
_isOne = num == ? YES : NO ;
self.label = [[UILabel alloc] initWithFrame: CGRectMake(,frame.size.height-,frame.size.width,)];
self.label.textAlignment = NSTextAlignmentCenter;//label 初始化
self.pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(frame.size.width - num * ,frame.size.height-,num * , )];
self.pageControl.numberOfPages = num;
self.indexc = ;
num = ;
self.scrollView = [[UIScrollView alloc]initWithFrame:frame];
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
self.scrollView.contentSize = CGSizeMake(frame.size.width * num , frame.size.height);
int i = ;
while(i < num){
UIView *v = [[UIView alloc]initWithFrame:CGRectMake(i * frame.size.width + marginL, marginT, frame.size.width - marginL - marginR, frame.size.height - marginT - marginB)];
v.clipsToBounds = YES;
[self.scrollView addSubview:v];
i++;
}
CGPoint point = CGPointMake(frame.size.width,);
self.scrollView.contentOffset = point;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.isCarousel = YES;//默认自动交换
self.isCarousel ? self.timer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(autochange) userInfo:nil repeats:YES] : nil;
}
- (int)checkindex:(int)temp
{
return (temp < ? temp = (int)(self.viewArray.count -) : (temp == (int)(self.viewArray.count) ? : temp));
}
- (void)autochange//自动切换
{
_isOne ? nil : [UIView animateWithDuration:(self.delay > 0.2 ? self.delay : 1.5 ) animations:^{ self.scrollView.contentOffset = CGPointMake( self.scrollView.frame.size.width * - , ); } completion:^(BOOL finished) { self.scrollView.contentOffset = CGPointMake( self.scrollView.frame.size.width * , ); }];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
self.scrollView.contentOffset = _isOne ? CGPointMake(self.scrollView.frame.size.width,) : self.scrollView.contentOffset ;// 只有一张图,强行不允许移动
if((int)self.scrollView.contentOffset.x == )
{
self.indexc = [self checkindex:--self.indexc];
[self changeimg];
}
if(fabs(self.scrollView.contentOffset.x - * self.scrollView.frame.size.width) < 1e-)
{
self.indexc = [self checkindex:++self.indexc];
[self changeimg];
}
}
- (void)changeimg
{
self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width,);
[self.scrollView.subviews[] addSubview:_viewArray[[self checkindex:(self.indexc-)]]];
[self.scrollView.subviews[] addSubview:_viewArray[[self checkindex:(self.indexc+)]]];
[self.scrollView.subviews[] addSubview:_viewArray[self.indexc]];
self.pageControl.currentPage = self.indexc;
_labeltitle ? [self.label setText:_labeltitle[self.indexc]]:nil;
}
- (void)setSubView:(NSArray *)viewArray
{
_viewArray = [[NSMutableArray alloc]initWithArray:viewArray];
[self changeimg];
}
- (void)setTitle:(NSArray *)title
{
_labeltitle = [[NSMutableArray alloc]initWithArray:title];
[self.label setText:_labeltitle[]];
}
@end

代码被封装了,可以直接用我写的这个类生成一个变量,代码中有对各个属性的解释

代码源文件