IOS中通过UICollectionView和UICollectionViewFlowLayout设置初始游标cursor来控制左右滑动来实现多条记录水平分页显示及控制音标读音

首先,应用到相关代理包括:
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




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值