赞
踩
2017.9.28更新(新增下拉轮播放大效果)github更新地址:点击打开链接
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- CGFloat offsetY = scrollView.contentOffset.y;
- if (offsetY >=0) {
- offsetY = 0;
- }
- [self.bannerView mas_updateConstraints:^(MASConstraintMaker *make) {
- make.top.equalTo(self.containerBackView).with.offset(offsetY);
- }];
- }
基本上每个App都会有需求要做轮播图,有些需求很简单,根本没什么花样,单纯的我以前自己用ScrollView写了一个真的是too yong too naive,根本没有复用好么,加载了那么多图片。
思路一
首先咱们有五张图片,那么我们就要在第一张和最后一张后面各放一张(共n+2),差不多就是
5 1 2 3 4 5 1,当用户从左1顺着滚动到右5的时候,再往后滚,显示出来的就是放在右5后面的右1图片,当这张欺骗用户的图片右1显示的时候,立刻把ScrollView的contentoffset设置到原先左1的位子,接着用户就可以继续向后滚动,这就是循环滚动,那么咱们亡国后滚动也是如此,当从左1滚动到左5的时候,当左5显示的时候,把ScrollView的ContentOffSet设置到右5的位子。这种做法当图片很多的时候,这不就坑爹了么!!!
思路二
这样看来性能根本就不好,图片全部加载出来了,如果非要考虑性能优化的话,也只能用三张图片进行操作,左中右三张图片就可以实现,每次滚动后就更新位子。
但是有个问题是它是当图片停止滚动的时候再去重新设置contentOffset的
当我们滚动到最后一页的时候,我们手指不移开,一直在那滑动,人家根本不会调用下面这个方法
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
也就是根本实现不了循环轮播了
思路三
我找到了
当我遇到了这个开源组件SDCycleScrollView
该组件是通过CollectionView来实现的,item的个数可以无限多,每个cell的复用就不会对性能产生影响,机智啊
它可以横着滚,竖着滚,文字滚,图片滚,文字图片一起滚。。。。。。以上这几种模式基本能满足工作上的需求,但是,有个需求根本满足不了我好么,这个咱们到最后介绍,先简单介绍下用法
进阶一 简单用法(下图展示的所有SD文件,箭头标注的是主要的两个)
- self.automaticallyAdjustsScrollViewInsets = NO;
- NSArray *images = @[@"http://twt.img.iwala.net/upload/118c59e1b27fd575.jpg",
- @"http://twt.img.iwala.net/upload/357797c67b3f7033.jpg",
- @"http://twt.img.iwala.net/upload/a9a69883ba624e67.jpg",
- @"http://twt.img.iwala.net/upload/858913320bff6162.jpg",
- @"http://twt.img.iwala.net/upload/21359667942b4065.jpg",
- @"http://twt.img.iwala.net/upload/93f0689ec10d5033.jpg"];
- [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
- self.tableView.rowHeight = 66;
-
- UIView *headBackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 150)];
- self.tableView.tableHeaderView = headBackView;
-
- self.bannerView = [SDCycleScrollView cycleScrollViewWithFrame:CGRectMake(0, 0, 375, 203) delegate:self placeholderImage:nil];
- // 一个Category给用颜色做ImageView 用15宽2高做一个长方形图片 当前图片
- self.bannerView.currentPageDotImage = [UIImage imageWithColor:[UIColor redColor] forSize:CGSizeMake(15, 2)];
- // 同上做一个 其他图片
- self.bannerView.pageDotImage = [UIImage imageWithColor:[UIColor whiteColor] forSize:CGSizeMake(15, 2)];
- // 加载网络数组图片 我个人认为这个就有点坑了,理论上这里只能给网络加载的图片实现轮播,但是如果你要DIY一些图片上的文字,就要修改源码了
- self.bannerView.imageURLStringsGroup = images;
- // 每张图对应的文字数组
- //self.bannerView.titlesGroup = @[@"第一张",@"第二章",@"第三章",@"第四章",@"第五章"];
- // 加载本地图片
- //self.bannerView.localizationImageNamesGroup = @[放本地图片];
- //默认两秒 自动滚动时间
- //self.bannerView.autoScrollTimeInterval = 5.0f;
- // 是否无限滚动 默认YES
- //self.bannerView.infiniteLoop = YES;
- // 是否自动滚动 是否自动滚动 默认YES
- //self.bannerView.autoScroll = YES;
- // 滚动方向 默认水平
- //self.bannerView.scrollDirection = UICollectionViewScrollDirectionVertical;
- [headBackView addSubview:self.bannerView];
这里有个小细节,UI美眉如果没有给咱们PageController的图片那可咋整呢,不怕,看下面这个UIImage的Category,给一个颜色和Size,画一个需要的就行了,脸皮够厚那就直接让你们的UI画一个吧
- + (UIImage*)imageWithColor:(UIColor *)color forSize:(CGSize)size
- {
- if (size.width <= 0 || size.height<= 0 )
- {
- return nil;
- }
- CGRect rect = CGRectMake(0, 0, size.width, size.height);
- UIGraphicsBeginImageContext(rect.size);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGContextSetFillColorWithColor(context, [color CGColor]);
- CGContextFillRect(context, rect);
- UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return img;
- }
进阶二 自定义用法(咱们自己加一个自定义View进去,有兴趣的可以用Xib试试)
说到自定义,我还特地发邮件给原作者让他给咱们出个接口可以自定义,暴露几个接口可以自定义应该会挺好用的。
估计人家看到邮件是这样的
需求如下,是要给这种样式进行轮播
看图大致就是底部是一个ImageView,但是如果是单单一个ImageView的话就好办了,直接用他的方法就可以实现了,传个数组进去就好了,但是还要加一个蒙版的头部在上面跟着滚动啊,折腾好久,逼我在你的源码上动刀子了(这样做确实用cocopods更新的话就不好了,但是一个轮播图嘛,咱就不打算更新你了,是你逼我的)
加入两个新增的文件之后
首先在SDCycleScrollView.h新增字段
- // 新增字段 //
- @property (nonatomic,assign) BOOL needMask;
- @property (nonatomic,copy) NSArray *countryNames;
- @property (nonatomic,copy) NSArray *countryNumbers;
然后在.m文件中增加方法,由于我们是要更改的Cell的样式而已,所以找到Cell的加载方法
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
具体实现如下
- if (self.needMask)
- {
- cell.mkjBannerMask.countryLabel.text = self.countryNames[itemIndex];
- NSMutableAttributedString *attribute = [[NSMutableAttributedString alloc] init];
- NSAttributedString *string1 = [[NSAttributedString alloc] initWithString:self.countryNumbers[itemIndex] attributes:
-
- @{NSFontAttributeName : [[[UIDevice currentDevice] systemVersion] floatValue] > 8.1 ?
- [UIFont systemFontOfSize:16 weight:UIFontWeightLight] : [UIFont fontWithName:@"HelveticaNeue-Light" size:16] ,
- NSForegroundColorAttributeName: [UIColor blackColor],
- NSBackgroundColorAttributeName : [UIColor colorWithRed:255 / 255.0 green:194 / 255.0 blue:1 / 255.0 alpha:1]}];
- NSAttributedString *string2 = [[NSAttributedString alloc] initWithString:@" 个单品" attributes:
- @{NSForegroundColorAttributeName : [UIColor whiteColor],
- NSFontAttributeName : [UIFont systemFontOfSize:16]}];
- [attribute appendAttributedString:string1];
- [attribute appendAttributedString:string2];
- cell.mkjBannerMask.productNumberLable.attributedText = attribute;
- cell.isShow = self.needMask;
- }
之后肯定在具体的cell加载里面进行需要的布局
- // 给Banner增加蒙版
- @property (nonatomic,strong) SDCustomMaskView *mkjBannerMask;
- @property (nonatomic,assign) BOOL isShow;
- - (instancetype)initWithFrame:(CGRect)frame
- {
- if (self = [super initWithFrame:frame]) {
- [self setupImageView];
- [self setupTitleLabel];
- // 新增蒙版View
- [self setupMaskView];
- }
-
- return self;
- }
- - (void)setupMaskView
- {
- SDCustomMaskView *customMask = [[SDCustomMaskView alloc] init];
- customMask.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.3];
- _mkjBannerMask = customMask;
- [self.contentView addSubview:customMask];
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
-
- _imageView.frame = self.bounds;
- // 最后一步,当布局cell子视图的时候调用,这个时候需要根据外部接口YES or NO来进行是否给Frame
- // 默认字段是NO,当YES的时候就加载,这里可以根据具体的需求随意更改,各位想怎么加载就加载什么样式
- if (self.isShow) {
- _mkjBannerMask.frame = self.bounds;
- }
- CGFloat titleLabelW = self.sd_width;
- CGFloat titleLabelH = _titleLabelHeight;
- CGFloat titleLabelX = 0;
- CGFloat titleLabelY = self.sd_height - titleLabelH;
- _titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);
- _titleLabel.hidden = !_titleLabel.text;
- }
效果如下 上面是没设置的自定义的,下面是开了自定义的,各位还想改成什么样式都随意,本身就是用collectionView的cell加载的,根据上面的思路改改Cell就OK啦
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。