赞
踩
(一) 无限滚动之UICollectionView
您好、
平时我们经常在图片浏览器中会翻看一些图片,对于这会滚动的效果实现,我们第一个直觉会想到的UIscrollview。首先我们会考虑到View的一些循环利用,一般情况下会创建两到三个View去实现它的来回的切换滚动。
不过今天虾米没用到这种方法。虾米用的是UICollectionView。
那下面 小虾米通过小作业来实现无限滚动,如果当中有什么不好的或者是需要改善的地方,请告诉我您的建议和意见。同时也可以联系虾米。
我们私下可以交流交流。。。。xieixe!!
自动滚动大致意图:
虾米先把大体需要用到的类都放在每一个对应位置上,方便以后查找某一个类和元素。
先浏览一下整体的classes。然后虾米再附上每一个类的代码实现 。 如下图:
我们先在故事板里,拉入一个UICollectionView(最好和图片的尺寸一样 )和一个UIPageController。如下图:
注意:根控制器的class要改为JHNewsController. 并且collectionView的代理和数据源方法为self(根控制器)
可以在collectionView上右击拉线给News Controller或者用代码实现。。。^-^ 嘻嘻。。。
然后,在根控制器当中我们必须遵守UICollectionView的一些协议。
虾米先把根控制器的主要实现代码po上。
大致为:
通过添加一个定时器实现三组数据的无限循环滚动。
主要方法是 [self.collectionView scrollToItemAtIndexPath: atScrollPosition: animated:YES]; 同时也要计算出需要展示的位置。
自动滚动下一页请详细看看我下面所写的方法 -(void)nextPage。
代码如下:
- // JHNewsController.m
- // 无限滚动-02新闻数据显示
- //
- // Created by cjj on 15-9-19.
- // Copyright (c) 2015年 jh.chen. All rights reserved.
- //
-
- #import "JHNewsController.h"
- #import "JHNewsCell.h"
- #import "JHNews.h"
- #import "MJExtension.h"
-
- #define JHReuseIdentifierCell @"news"
- #define JHMaxSection 3
-
- @interface JHNewsController () <UICollectionViewDataSource,UICollectionViewDelegate>
- @property (nonatomic, strong) NSArray *newses;
- @property (nonatomic, strong) NSTimer *timer;
- @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
- @property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
-
- @end
-
- @implementation JHNewsController
- - (NSArray *)newses
- {
- if (_newses == nil) {
- self.newses = [JHNews objectArrayWithFilename:@"newses.plist"];
- self.pageControl.numberOfPages = self.newses.count;
- }
- return _newses;
- }
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
- // 注册cell
- [self.collectionView registerNib:[UINib nibWithNibName:@"JHNewsCell" bundle:nil] forCellWithReuseIdentifier:JHReuseIdentifierCell];
-
- // "默认"显示最中间那组
- [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:JHMaxSection / 2] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
-
- // 添加定时器
- [self addTimer];
- }
-
- /*
- * 添加定时器
- */
- -(void)addTimer
- {
- NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
-
- [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
- self.timer = timer;
- }
-
-
- -(void)nextPage
- {
- // 1.显示当前的位置信息
- NSIndexPath *currentIndexPath = [[self.collectionView indexPathsForVisibleItems] lastObject];
-
- // 马上显示中间那组的数据
- NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:JHMaxSection / 2];
- [self.collectionView scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
-
- // 2.计算出下一个需要展示的位置
- NSUInteger nextItem = currentIndexPathReset.item + 1;
- NSUInteger nextSection = currentIndexPathReset.section;
- if (nextItem == self.newses.count) {
- nextItem = 0;
- nextSection ++;
- }
- NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];
-
- // 3.通过动画滚动到下一个位置
- [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
- }
-
- /*
- * 移除定时器
- */
- -(void)removeTimer
- {
- [self.timer invalidate];
- self.timer = nil;
- }
-
-
-
-
- #pragma mark - UICollectionViewDataSource
- - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
- {
- return self.newses.count;
- }
-
- -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
- {
- return JHMaxSection;
- }
-
- - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
- {
- JHNewsCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:JHReuseIdentifierCell forIndexPath:indexPath];
-
- cell.news = self.newses[indexPath.item];
-
- return cell;
- }
-
- #pragma mark - UICollectionViewDelegate
-
- /**
- * 当用户开始拖拽时就会调用
- */
- -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
- {
- [self removeTimer];
- }
-
- /**
- * 当用户停止拖拽时就会调用
- */
- -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
- {
- [self addTimer];
- }
-
- -(void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- // 显示下一页
- int page = (int)(scrollView.contentOffset.x / scrollView.bounds.size.width + 0.5) % self.newses.count;
- self.pageControl.currentPage =page;
- }
-
- @end
另外。。。我们有必要了解下JHNewsCell,虾米通过继承UICollectionViewCell,并创建附有一个Xib属性。里面封装着一个UIImageView和一个UILabel。
.h文件留下一个接口,让别人传递数据进来,我们拿到外边传进来的数据在.m文件通过set方法实现。。。
详细代码如下:
- //
- // JHNewsCell.m
- // 无限滚动-02新闻数据显示
- //
- // Created by cjj on 15-9-19.
- // Copyright (c) 2015年 jh.chen. All rights reserved.
- //
-
- #import "JHNewsCell.h"
- #import "JHNews.h"
-
- @interface JHNewsCell()
-
- @property (weak, nonatomic) IBOutlet UILabel *titleLabel;
- @property (weak, nonatomic) IBOutlet UIImageView *iconView;
-
- @end
-
-
- @implementation JHNewsCell
-
-
- - (void)setNews:(JHNews *)news
- {
- _news = news;
- self.iconView.image = [UIImage imageNamed:news.icon];
- self.titleLabel.text = [NSString stringWithFormat:@" %@",news.title];
- }
-
- @end
(二) BUG解决措施
在写这份demo的时候,遇到一些让我纠结了半天而程序莫名崩溃的bug,为此虾米把它记录了下来。
上面写的代码,检查了很多遍都没有问题。但运行时出现了错误,报如下的错误:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'invalid nib registered for identifier (news) - nib must contain exactly one top level object which must be a UICollectionReusableView instance’
最终还是被我找到了错误原因:在自定义xib的时候,额外多了一个控件在cell另外的区域,把该控件删除即可。
如图:
把多余的UIImageView删除即可,说到底还是自己太马虎从而犯了简单的错误了。
如果有什么好的建议,请联系虾米,虾米感激不尽 蟹蟹 哈!!
虾米联系方式:
QQ:584837022
github:https://github.com/ios-cjh
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。