首先,应用到相关代理包括:
UIScrollViewDelegate, 游标cursor滑动控制显示第几个数据,可根据cursor获取相关对象里边的值。如声音播放链接地址,标题名称等。
UICollectionViewDataSource, 数据加载代理
UICollectionViewDelegate, cell视图显示代理
每屏单个元素的Flowlayout控制如下:
UIScrollViewDelegate, 游标cursor滑动控制显示第几个数据,可根据cursor获取相关对象里边的值。如声音播放链接地址,标题名称等。
UICollectionViewDataSource, 数据加载代理
UICollectionViewDelegate, cell视图显示代理
UICollectionViewDelegateFlowLayout cell元素控制
实现的效果图如下:
部分代码实例如下:
@interface TopicCollectionViewController ()<UIScrollViewDelegate,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>
{
NSInteger _bid; //ID
UICollectionView *_collectionView; //当前collectionView
NSIndexPath *_indexPath;
NSMutableArray *_itemAry; //当前数据缓存
NSInteger _total; //数据记录总数
NSInteger _cursor; //当前页
NSInteger _currentSkip;
BOOL _hasAutoread; //是否允话自动发音
AVAudioPlayer *_avAudioPlayer;
}
@property(nonatomic,strong)MBProgressHUD *hud;
@end
@implementation TopicCollectionViewController
#pragma mark sysLoad
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_itemAry = [[NSMutableArray alloc] init];
}
return self;
}
/**
* 收藏滑动列表
* @param int aID ID
* @param array aItemAry 数据
* @param int aTotal 数据总数
* @param int aCursor 当前游标
*/
- (id)initWithID:(NSInteger)aID itemAry:(NSMutableArray *)aItemAry total:(NSInteger)aTotal cursor:(NSInteger)aCursor
{
if (self = [super init]) {
_bid = aID;
_itemAry = aItemAry;
_total = aTotal;
_cursor = aCursor;
[self setNavTitle:@"我的收藏"];
}
return self;
}
/**
* 加载视图
*/
- (void)loadView
{
//设置当前视图背景色
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, DT_SCREEN_MAIN_WIDTH, DT_SCREEN_MAIN_HEIGHT)];
self.view.backgroundColor = [UIColor clearColor];
[self addNavBarView];
_hasAutoread = [[NSUserDefaults standardUserDefaults] boolForKey:@"EnglishAutoread"];
[self addCollectionView];
}
#pragma mark sysLoad
- (void)viewDidLoad
{
[super viewDidLoad];
[self initData];
//当前页
[MobClick logPageView:self.screenName seconds:kUmengTrackingIntervalTime];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[(CustomNavViewController *)self.navigationController removeGestureRecognizer];
[MobClick beginLogPageView:self.screenName];
}
// Called when the view is about to made visible. Default does nothing
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//播放声音
if(_bid == BOOK_TYPE_ENGLISH && _cursor < [_itemAry count]){
EnglishObject *_englishObject = _itemAry[_cursor];
[self audioPlayer:_englishObject.sound];
}
}
/**
* 释放内存
*/
- (void)dealloc
{
}
/**
* 顶部导航
*/
- (void)addNavBarView
{
}
/**
* 返回事件
*/
- (void)leftBtnTap
{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark addTableView
- (void)addCollectionView
{
//样式部局设定
TopicViewFlowLayout *flowLayout = [[TopicViewFlowLayout alloc] init];
//水平滑动
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, DT_SCREEN_MAIN_WIDTH, DT_SCREEN_MAIN_HEIGHT) collectionViewLayout:flowLayout];
[_collectionView registerClass:[BookTopicCollectionViewCell class] forCellWithReuseIdentifier:[NSString stringWithFormat:@"_collectCell_%d", _bid]];
[_collectionView setBackgroundColor:[UIColor whiteColor]];
[_collectionView setUserInteractionEnabled:YES];
[_collectionView setPagingEnabled:YES];
[_collectionView setDelegate:self];
[_collectionView setDataSource:self];
[self.view addSubview:_collectionView];
}
/**
* 集合代理-每一部分数据项
*/
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return _total;
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
/**
* 定义每个UICollectionView 的大小
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(DT_SCREEN_MAIN_WIDTH, DT_SCREEN_MAIN_HEIGHT);
}
/**
* 复用Cell
*/
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = [NSString stringWithFormat:@"_collectCell_%d", _bid];
BookTopicCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
//更新Cell数据
if (indexPath.row<[_itemAry count]) {
switch (_bid) {
case BOOK_TYPE_POLITICAL: //政治
[cell updateWithPoliticalObject:_itemAry[indexPath.row] delegate:self row:indexPath.row];
break;
case BOOK_TYPE_ENGLISH: //英语高频词汇
[cell updateWithEnglishObject:_itemAry[indexPath.row] delegate:self row:indexPath.row];
break;
case BOOK_TYPE_ENGLISH_CORE: //英语核心考点
[cell updateWithEnglishCoreObject:_itemAry[indexPath.row] delegate:self row:indexPath.row];
break;
case BOOK_TYPE_MATH: //数学
[cell updateWithMatchObject:_itemAry[indexPath.row] delegate:self row:indexPath.row];
break;
}
}
return cell;
}
/**
* 代理-选择行的触发事件
*/
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//NSLog(@"--------: %d %d", indexPath.section, indexPath.row);
}
- (void)selectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition
{
}
/**
* 滑动时
*/
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//得到每页宽度
CGFloat pageWidth = scrollView.frame.size.width;
// 根据当前的x坐标和页宽度计算出当前页数
_cursor = floor((scrollView.contentOffset.x - pageWidth/2)/pageWidth) + 1;
}
/**
* 当手离开时
*/
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
//得到每页宽度
if (decelerate){
if ((_cursor+1) >= [_itemAry count]) {
[self FDPullTrigger];
}
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//播放声音
if(_bid == BOOK_TYPE_ENGLISH && _cursor < [_itemAry count]){
EnglishObject *_englishObject = _itemAry[_cursor];
[self audioPlayer:_englishObject.sound];
}
}
//初始化
- (void)initData
{
_itemAry = [BookDataRequest singleton].topicCollAry;
_total = [BookDataRequest singleton].total;
[LoadingView hideLoadView];
_collectionView.contentOffset = CGPointMake(_cursor*DT_SCREEN_MAIN_WIDTH, _collectionView.frame.origin.y);
[_collectionView reloadData];
}
/**
* 达到触发条件-触发更新事件
*/
- (void)FDPullTrigger
{
__block __weak UICollectionView *_weakCollectionView = _collectionView;
[[BookDataRequest singleton] getTopicCollectWithList:_bid isAll:YES refresh:NO completeBlock:^() {
[LoadingView hideLoadView];
_itemAry = [BookDataRequest singleton].topicCollAry;
[_weakCollectionView reloadData];
} failedBlock:^(NSString *errcode, NSString *errmsg) {
[LoadingView hideLoadView];
[ToastAlert showInView:[UIApplication sharedApplication].windows[0] Image:nil String:NO_NETWORK_TIPS];
}];
}
#pragma mark-audioPlayer
/**
* 播放url地址(在线流媒体请求)
*
* @param string *aUrlString 音频播放地址
*/
- (void)audioPlayer:(NSString *)aUrlString
{
if (aUrlString.length == 0 || _englishAutoread == NO || [aUrlString isEqualToString:@""]) {
return;
}
if([SystemUtility NoNetwork]){
NSFileManager *fileManager = [NSFileManager defaultManager];
//MD5音频文件名
NSString *fileName = [NSString stringWithFormat:@"%@.wav",[EnglishDataRequest md5Key:aUrlString]];
//创建附件存储目录
if ([fileManager fileExistsAtPath:fileName] && _avAudioPlayer.playing == FALSE) {
NSData *audioData = [NSData dataWithContentsOfFile:fileName];
//音频播放
_avAudioPlayer =[[AVAudioPlayer alloc] initWithData:audioData error:nil];
_avAudioPlayer.numberOfLoops=0;
[_avAudioPlayer play];
}
return;
}
//判断网络是否在Wifi状态
if (![SystemUtility IsEnableWIFI]) {
return;
}
//读取音频数据
[[EnglishDataRequest singleton] playAudioWithWords:aUrlString completeBlock:^() {
//音频播放
if (_avAudioPlayer.playing == FALSE && [EnglishDataRequest singleton].audioData != nil) {
_avAudioPlayer =[[AVAudioPlayer alloc] initWithData:[EnglishDataRequest singleton].audioData error:nil];
_avAudioPlayer.numberOfLoops=0;
[_avAudioPlayer play];
}
} failedBlock:^(NSString *errcode, NSString *errmsg) {
}];
}
@end
每屏单个元素的Flowlayout控制如下:
#import "TopicViewFlowLayout.h"
@implementation TopicViewFlowLayout
#define ITEM_SIZE DT_SCREEN_MAIN_WIDTH
#define ACTIVE_DISTANCE DT_SCREEN_MAIN_WIDTH
#define ZOOM_FACTOR 0.3
-(id)init
{
self = [super init];
if (self) {
self.itemSize = CGSizeMake(DT_SCREEN_MAIN_WIDTH, DT_SCREEN_MAIN_HEIGHT);
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
//self.sectionInset = UIEdgeInsetsMake(0, 0.0, 0, 0.0);
self.minimumLineSpacing = 0.0;
}
return self;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)oldBounds
{
return YES;
}
/**
* item属性设置(去掉动画,直接水平滑)
*/
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes* attributes in array) {
if (CGRectIntersectsRect(attributes.frame, rect)) {
CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
//CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
if (ABS(distance) < ACTIVE_DISTANCE) {
//CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));
//attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
attributes.zIndex = 1;
}
}
}
return array;
}
/**
* 每个item宽度控制
*/
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds)); ///2.0
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray* array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes* layoutAttributes in array) {
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
offsetAdjustment = itemHorizontalCenter - horizontalCenter;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
@end