iOS开发-实现上下翻转轮播循环信息播报效果

news2024/9/22 21:22:00

iOS开发-实现上下翻转轮播循环信息播报效果

在开发中经常遇到需要实现轮播信息播报,例如以下效果

在这里插入图片描述

在这里插入图片描述

一、使用UITableView实现展示列表

UITableView
定义UITableView的实例,并让当前视图遵守UITableView的两个协议

@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;

初始化UITableView

_tableView = [[DFBaseTableView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.backImageView.frame), CGRectGetHeight(self.backImageView.frame)) style:UITableViewStylePlain];
_tableView.backgroundColor = [UIColor clearColor];
_tableView.showsHorizontalScrollIndicator = NO;
_tableView.showsVerticalScrollIndicator = NO;
_tableView.userInteractionEnabled = YES;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.clipsToBounds = YES;
_tableView.pagingEnabled = YES;
_tableView.scrollEnabled = NO;
[self.backImageView addSubview:_tableView];

实现dataSource与delegate协议

#pragma mark - TableViewDataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataItems.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = nil;
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(cellForBroadcast:atIndex:)]) {
        cell = [self.dataSource cellForBroadcast:tableView atIndex:indexPath];
    }
    
    if (cell) {
        return cell;
    }
    
    static NSString *identifier = @"adefaultCell";
    UITableViewCell *defaultCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (!defaultCell) {
        defaultCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    
    defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    return defaultCell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return CGRectGetHeight(self.tableView.frame);
}

二、定时器NSTimer

开启定时器NSTimer重新设置setContentOffset。

[_tableView setContentOffset:CGPointMake(0.0, targetY) animated:animated];

实现定时器NSTimer

/**
 开启定时器
 */
- (void)addDisplayTimer {
    if (!_displayTimer) {
        self.displayTimer = [NSTimer timerWithTimeInterval:AutoPlayTimeInterval target:self selector:@selector(switchImageItem) userInfo:nil repeats:YES];
        
        [[NSRunLoop currentRunLoop] addTimer:self.displayTimer forMode:NSRunLoopCommonModes];
    }
}

/**
 移除定时器
 */
- (void)removeDisplayTimer {
    [self.displayTimer invalidate];
    self.displayTimer = nil;
}

/**
 翻页
 */
- (void)switchImageItem {
    CGFloat targetY = _tableView.contentOffset.y + _tableView.frame.size.height;
    targetY = (int)(targetY/CGRectGetHeight(self.tableView.frame)) * CGRectGetHeight(self.tableView.frame);
    [self setScrollViewContentOffset:targetY animated:YES];
}

三、实现循环展示

实现循环展示时候,需要设置将第一条数据加入到最后一条。展示列表为需要获取的列表数据的length+2;

代码如下

- (void)setBroadcastItems {
    
    //添加最后一张图 用于循环
    NSInteger length = self.bcastItems.count;
    NSMutableArray *itemBroadcastArray = [NSMutableArray arrayWithCapacity:length+2];
    if (length > 1) {
        DFAppMainPageCastContentItem *model = [self.bcastItems objectAtIndex:length-1];
        [itemBroadcastArray addObject:model];
    }
    
    for (int i = 0; i < length; i++) {
        DFAppMainPageCastContentItem *model = [self.bcastItems objectAtIndex:i];
        [itemBroadcastArray addObject:model];
    }
    
    //添加第一张图 用于循环
    if (length > 1) {
        DFAppMainPageCastContentItem *model = [self.bcastItems objectAtIndex:0];
        [itemBroadcastArray addObject:model];
    }
    
    self.broadCastItems = itemBroadcastArray;
}

UITableView继承UIScrollView,实现UIScrollViewDelegate中的方法。

如果当偏移量scrollView.contentOffset.y达到最后一条的时候,设置setContentOffsett到第一条的偏移量

float targetY = scrollView.contentOffset.y;
NSArray *aDataItems = self.dataItems;
if ([aDataItems count] >= 3) {
    if (targetY >= CGRectGetHeight(self.tableView.frame) * ([aDataItems count] -1)) {
        targetY = CGRectGetHeight(self.tableView.frame);
        [self setScrollViewContentOffset:targetY animated:NO];
    } else if (targetY <= 0) {
        targetY = CGRectGetHeight(self.tableView.frame)*([aDataItems count]-2);
        [self setScrollViewContentOffset:targetY animated:NO];
    }
}

三、定义的数据的数组及cell协议

定义的数据的数组及cell协议DFAppMainPageCastContentDataSource和DFAppMainPageCastContentDelegate
外部实现DFAppMainPageCastContentDataSource和DFAppMainPageCastContentDelegate,可以设置自定义UITableViewCell与展示数据。

@protocol DFAppMainPageCastContentDataSource <NSObject>
@optional

/**
 设置item数据源
 
 @return 数据源
 */
- (NSArray *)itemsForBroadcast;

/**
 数据源指定的子控件
 
 @param indexPath 索引
 @return 子控件
 */
- (UITableViewCell *)cellForBroadcast:(UITableView *)tableView atIndex:(NSIndexPath *)indexPath;

@end

@protocol DFAppMainPageCastContentDelegate <NSObject>
@optional

/**
 点击的当前界面

 @param index 下标
 */
- (void)broadcastDidSelectItem:(NSInteger)index;

@end

四、实现轮播展示

实现轮播展示控件

DFAppMainPageCastContentView.h

#import <UIKit/UIKit.h>
#import "DFAppMainPageCastContentCell.h"

#pragma mark -
#pragma mark - 此类用于处理上下滚动UI播报

@interface DFAppMainPageCastContentItem : NSObject

@property (nonatomic, strong) UIColor *color;
@property (nonatomic, strong) NSString *aIndex;

@property (nonatomic, strong) id extObject;

/**
 为数据源数组中添加第一个位置添加一条最后的元素、最后一个位置添加一条第一个元素

 @param originItems 原数组
 @return 新数组
 */
+ (NSMutableArray *)broadcastItems:(NSArray *)originItems;

@end

/**
 此类用于处理上下滚动UI播报
 */
@protocol DFAppMainPageCastContentDataSource;
@protocol DFAppMainPageCastContentDelegate;

@interface DFAppMainPageCastContentView : UIView<UIGestureRecognizerDelegate, UIScrollViewDelegate>

@property (nonatomic, weak) id<DFAppMainPageCastContentDataSource>dataSource;
@property (nonatomic, weak) id<DFAppMainPageCastContentDelegate>delegate;

@property (nonatomic, assign, readonly) BOOL isAutoPlay;
@property (nonatomic, assign) NSInteger pageNumber;
@property (nonatomic, assign) BOOL showPageDot;

- (id)initWithFrame:(CGRect)frame
         isAutoPlay:(BOOL)isAutoPlay;

/**
 载入数据,创建控件
 */
- (void)reloadBroadcastData;

/**
 滚动到指定页page
 
 @param aIndex aindex
 */
- (void)scrollViewByIndex:(int)aIndex;

/**
 启动定时器
 */
- (void)startDisplayTimer;

/**
 终止定时器
 */
- (void)stopDisplayTimer;

@end

@protocol DFAppMainPageCastContentDataSource <NSObject>
@optional

/**
 设置item数据源
 
 @return 数据源
 */
- (NSArray *)itemsForBroadcast;

/**
 数据源指定的子控件
 
 @param indexPath 索引
 @return 子控件
 */
- (UITableViewCell *)cellForBroadcast:(UITableView *)tableView atIndex:(NSIndexPath *)indexPath;

@end

@protocol DFAppMainPageCastContentDelegate <NSObject>
@optional

/**
 点击的当前界面

 @param index 下标
 */
- (void)broadcastDidSelectItem:(NSInteger)index;

@end

DFAppMainPageCastContentView.m

#import "DFAppMainPageCastContentView.h"
#import <objc/runtime.h>

static CGFloat MPageControlWidth = 60.0;
static CGFloat MPageControlHeight = 20.0;

static CGFloat kPadding = 5.0;

static CGFloat AutoPlayTimeInterval = 3.0;
static NSInteger kDefaultTag = 20171101;

static NSString *MSCrollViewKey = @"circleScrollView";

@implementation DFAppMainPageCastContentItem

/**
 为数据源数组中添加第一个位置添加一条最后的元素、最后一个位置添加一条第一个元素
 
 @param originItems 原数组
 @return 新数组
 */
+ (NSMutableArray *)broadcastItems:(NSArray *)originItems {
    //添加最后一张图 用于循环
    NSInteger length = originItems.count;
    NSMutableArray *itemBroadcastArray = [NSMutableArray arrayWithCapacity:length+2];
    if (length > 1) {
        UIColor *color = [originItems objectAtIndex:length-1];
        [itemBroadcastArray addObject:color];
    }
    
    for (int i = 0; i < length; i++) {
        UIColor *color = [originItems objectAtIndex:i];
        [itemBroadcastArray addObject:color];
    }
    
    //添加第一张图 用于循环
    if (length > 1) {
        UIColor *color = [originItems objectAtIndex:0];
        [itemBroadcastArray addObject:color];
    }
    
    return itemBroadcastArray;
}

@end


@interface DFAppMainPageCastContentView ()<UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UIImageView *backImageView;
@property (nonatomic, strong) DFBaseTableView *tableView;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, assign, readwrite) BOOL isAutoPlay;
@property (nonatomic, strong) NSArray *dataItems;
@property (nonatomic, strong) NSTimer *displayTimer;

@end

@implementation DFAppMainPageCastContentView

- (id)initWithFrame:(CGRect)frame
         isAutoPlay:(BOOL)isAutoPlay {
    
    self = [super initWithFrame:frame];
    if (self) {
        
        self.backgroundColor = [UIColor clearColor];
        
        _isAutoPlay = isAutoPlay;
        
        _backImageView = [[UIImageView alloc] initWithFrame:self.bounds];
        _backImageView.backgroundColor = [UIColor clearColor];
        _backImageView.userInteractionEnabled = YES;
        [self addSubview:_backImageView];
        
        _tableView = [[DFBaseTableView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.backImageView.frame), CGRectGetHeight(self.backImageView.frame)) style:UITableViewStylePlain];
        _tableView.backgroundColor = [UIColor clearColor];
        _tableView.showsHorizontalScrollIndicator = NO;
        _tableView.showsVerticalScrollIndicator = NO;
        _tableView.userInteractionEnabled = YES;
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.clipsToBounds = YES;
        _tableView.pagingEnabled = YES;
        _tableView.scrollEnabled = NO;
        [self.backImageView addSubview:_tableView];
        
        UITapGestureRecognizer *tapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognizer:)];
        tapGestureRecognize.delegate = self;
        tapGestureRecognize.numberOfTapsRequired = 1;
        [_tableView addGestureRecognizer:tapGestureRecognize];
        
        _pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(kPadding, 0, MPageControlHeight, MPageControlWidth)];
        [_backImageView addSubview:_pageControl];
        _pageControl.transform = CGAffineTransformMakeRotation(M_PI/2);
                
        if ([self.tableView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
            if (@available(iOS 11.0, *)) {
                self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
            } else {
                // Fallback on earlier versions
            }
        }
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.backImageView.frame = self.bounds;
    self.tableView.frame = CGRectMake(0, 0, CGRectGetWidth(self.backImageView.frame), CGRectGetHeight(self.backImageView.frame));
    self.pageControl.frame = CGRectMake(kPadding, (CGRectGetHeight(self.backImageView.frame) - MPageControlWidth)/2, MPageControlHeight, MPageControlWidth);
    self.pageControl.transform = CGAffineTransformMakeRotation(M_PI/2);
}

#pragma mark -
#pragma mark - SETTER属性
/**
 设置pageControl页码
 
 @param pageNumber 页码
 */
- (void)setPageNumber:(NSInteger)pageNumber {
    _pageNumber = pageNumber;
    self.pageControl.numberOfPages = pageNumber;
}

/**
 设置pageControl是否显示
 
 @param showPageDot 是否显示
 */
- (void)setShowPageDot:(BOOL)showPageDot {
    _showPageDot = showPageDot;
    self.pageControl.hidden = !showPageDot;
}

#pragma mark -
#pragma mark - 载入数据,创建控件
/**
 载入数据,创建控件
 */
- (void)reloadBroadcastData {
    NSArray *items = nil;
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(itemsForBroadcast)]) {
        items = [self.dataSource itemsForBroadcast];
    }
    
    self.dataItems = nil;
    self.dataItems = [[NSArray alloc] initWithArray:items];
    
    [self.tableView reloadData];
    [self setupSubViews];
}

/**
 创建控件
 */
- (void)setupSubViews {
    [self removeDisplayTimer];
    
    if ([self.dataItems count] > 1) {
        [self setScrollViewContentOffset:CGRectGetHeight(self.tableView.frame) animated:NO];
        if (_isAutoPlay) {
            [self addDisplayTimer];
        }
    }
}

#pragma mark - TableViewDataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataItems.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = nil;
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(cellForBroadcast:atIndex:)]) {
        cell = [self.dataSource cellForBroadcast:tableView atIndex:indexPath];
    }
    
    if (cell) {
        return cell;
    }
    
    static NSString *identifier = @"adefaultCell";
    UITableViewCell *defaultCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (!defaultCell) {
        defaultCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    
    defaultCell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    return defaultCell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return CGRectGetHeight(self.tableView.frame);
}

#pragma mark - DisplayTimer
/**
 开启定时器
 */
- (void)addDisplayTimer {
    if (!_displayTimer) {
        self.displayTimer = [NSTimer timerWithTimeInterval:AutoPlayTimeInterval target:self selector:@selector(switchImageItem) userInfo:nil repeats:YES];
        
        [[NSRunLoop currentRunLoop] addTimer:self.displayTimer forMode:NSRunLoopCommonModes];
    }
}

/**
 移除定时器
 */
- (void)removeDisplayTimer {
    [self.displayTimer invalidate];
    self.displayTimer = nil;
}

/**
 翻页
 */
- (void)switchImageItem {
    CGFloat targetY = _tableView.contentOffset.y + _tableView.frame.size.height;
    targetY = (int)(targetY/CGRectGetHeight(self.tableView.frame)) * CGRectGetHeight(self.tableView.frame);
    [self setScrollViewContentOffset:targetY animated:YES];
}

/**
 点击scrollView每一个控件
 
 @param tap 点击手势
 */
- (void)tapGestureRecognizer:(UITapGestureRecognizer *)tap {
    NSInteger page = (NSInteger)(_tableView.contentOffset.y / _tableView.frame.size.height);
    if (page > -1 && page < self.dataItems.count) {
        if ([self.delegate respondsToSelector:@selector(broadcastDidSelectItem:)]) {
            [self.delegate broadcastDidSelectItem:page];
        }
    }
}

#pragma mark -
#pragma mark - ContentOffset
/**
 设置Scroll的偏移量
 
 @param targetY 偏移量Y
 @param animated 是否有动画
 */
- (void)setScrollViewContentOffset:(CGFloat)targetY animated:(BOOL)animated {
    [_tableView setContentOffset:CGPointMake(0.0, targetY) animated:animated];
}

/**
 滚动到指定页page
 
 @param aIndex aindex
 */
- (void)scrollViewByIndex:(int)aIndex {
    NSArray *aDataItems = self.dataItems;
    if ([aDataItems count]>1) {
        if (aIndex >= ([aDataItems count]-2)) {
            aIndex = (int)[aDataItems count]-3;
        }
        [self setScrollViewContentOffset:CGRectGetHeight(self.tableView.frame)*(aIndex+1) animated:YES];
    } else {
        [self setScrollViewContentOffset:0 animated:YES];
    }
    [self scrollViewDidScroll:_tableView];
}

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    float targetY = scrollView.contentOffset.y;
    NSArray *aDataItems = self.dataItems;
    if ([aDataItems count] >= 3) {
        if (targetY >= CGRectGetHeight(self.tableView.frame) * ([aDataItems count] -1)) {
            targetY = CGRectGetHeight(self.tableView.frame);
            [self setScrollViewContentOffset:targetY animated:NO];
        } else if (targetY <= 0) {
            targetY = CGRectGetHeight(self.tableView.frame)*([aDataItems count]-2);
            [self setScrollViewContentOffset:targetY animated:NO];
        }
    }
    int page = (_tableView.contentOffset.y+CGRectGetHeight(self.tableView.frame)/2.0) / CGRectGetHeight(self.tableView.frame);
    NSLog(@"page:%d",page);
    
    if ([aDataItems count] > 1) {
        page --;
        if (page >= _pageControl.numberOfPages) {
            page = 0;
        } else if(page <0) {
            page = (int)_pageControl.numberOfPages -1;
        }
    }
    
    _pageControl.currentPage = page;
    [_pageControl setCurrentPage:page];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (!decelerate) {
        CGFloat targetY = _tableView.contentOffset.y + _tableView.frame.size.height;
        targetY = (int)(targetY/CGRectGetHeight(self.tableView.frame)) * CGRectGetHeight(self.tableView.frame);
        [self setScrollViewContentOffset:targetY animated:NO];
    }
}

- (void)scrollViewByPageControlPage:(NSInteger)page {
    [self setScrollViewContentOffset:CGRectGetHeight(self.tableView.frame)*page animated:NO];
}

//开始拖拽视图
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    
}

#pragma mark -
#pragma mark - 启动定时器/终止定时器
/**
 启动定时器
 */
- (void)startDisplayTimer {
    if (_isAutoPlay) {
        [self addDisplayTimer];
    }
}

/**
 终止定时器
 */
- (void)stopDisplayTimer {
    [self removeDisplayTimer];
}

- (void)dealloc {
    [self removeDisplayTimer];
    _tableView.delegate = nil;
    _dataItems = nil;
    _dataSource = nil;
    _delegate = nil;
    _tableView = nil;
    _pageControl = nil;
}

@end

展示的轮播cell

DFAppMainPageCastContentCell.h

#import <UIKit/UIKit.h>
#import "DFAppMainPageBoardCastModel.h"

@protocol DFAppMainPageCastContentCellDelegate;
@interface DFAppMainPageCastContentCell : UITableViewCell

@property (nonatomic, weak) id<DFAppMainPageCastContentCellDelegate>actionDelegate;

@property (nonatomic, strong) DFAppMainPageBoardCastModel *showModel;

@end

@protocol DFAppMainPageCastContentCellDelegate <NSObject>

- (void)castContentButtonDidAction:(DFAppMainPageCastContentCell *)cell;

@end

DFAppMainPageCastContentCell.m

#import "DFAppMainPageCastContentCell.h"
#import "UIColor+Addition.h"

static CGFloat kHBGPadding = 15.0;

static CGFloat kIconSize = 15.0f;

static CGFloat kMidPadding = 15.0f;

static CGFloat kShowButtonWidth = 70.0;
static CGFloat kShowButtonHeight = 22.0;

@interface DFAppMainPageCastContentCell ()

@property (nonatomic, strong) UIImageView *backImageView;

@property (nonatomic, strong) UIImageView *iconImageView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *showButton;

@end

@implementation DFAppMainPageCastContentCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        
        self.backgroundColor = [UIColor clearColor];
        self.contentView.backgroundColor = [UIColor clearColor];
        
        [self.contentView addSubview:self.backImageView];
        [self.backImageView addSubview:self.titleLabel];
        [self.backImageView addSubview:self.iconImageView];
        [self.backImageView addSubview:self.showButton];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.backImageView.frame = CGRectMake(kHBGPadding, 0.0, CGRectGetWidth(self.bounds) - 2*kHBGPadding, CGRectGetHeight(self.bounds));
    
    CGFloat shouBGW = CGRectGetWidth(self.backImageView.frame);
    CGFloat shouBGH = CGRectGetHeight(self.backImageView.frame);

    CGSize buttonSize = [self.showButton.currentTitle sizeWithFont:self.showButton.titleLabel.font forMaxSize:CGSizeMake(kShowButtonWidth, kShowButtonHeight)];
    CGFloat showBtnW = ceil(buttonSize.width) + 20.0;
    self.showButton.frame = CGRectMake(shouBGW - showBtnW, (shouBGH - kShowButtonHeight)/2.0, showBtnW, kShowButtonHeight);

    self.iconImageView.frame = CGRectMake(0.0, (shouBGH - kIconSize)/2.0, kIconSize, kIconSize);

    self.titleLabel.frame = CGRectMake(CGRectGetMaxX(self.iconImageView.frame) + kMidPadding, 0.0, CGRectGetMinX(self.showButton.frame) - CGRectGetMaxX(self.iconImageView.frame) - 2*kMidPadding, CGRectGetHeight(self.backImageView.frame));
}

- (void)setShowModel:(DFAppMainPageBoardCastModel *)showModel {
    _showModel = showModel;
    self.titleLabel.text = showModel.showTextContent;
    
    NSString *showType = showModel.showType;
    if (showType.intValue%7 == 0) {
        [self.showButton setTitle:@"0元享" forState:UIControlStateNormal];
    } else if (showType.intValue%7 == 1) {
        [self.showButton setTitle:@"限时抢" forState:UIControlStateNormal];
    } else if (showType.intValue%7 == 2) {
        [self.showButton setTitle:@"去抽奖" forState:UIControlStateNormal];
    } else if (showType.intValue%7 == 3) {
        [self.showButton setTitle:@"速抢" forState:UIControlStateNormal];
    } else if (showType.intValue%7 == 4) {
        [self.showButton setTitle:@"去帮扶" forState:UIControlStateNormal];
    } else if (showType.intValue%7 == 5) {
        [self.showButton setTitle:@"9.9元抢" forState:UIControlStateNormal];
    } else if (showType.intValue%7 == 6) {
        [self.showButton setTitle:@"抽" forState:UIControlStateNormal];
    } else {
        [self.showButton setTitle:@"去助学" forState:UIControlStateNormal];
    }
    [self setNeedsLayout];
}

#pragma mark - ACTIONS
- (void)showButtonAction {
    if (self.actionDelegate && [self.actionDelegate respondsToSelector:@selector(castContentButtonDidAction:)]) {
        [self.actionDelegate castContentButtonDidAction:self];
    }
}

#pragma mark - SETTER/GETTER
- (UIImageView *)backImageView {
    if (!_backImageView) {
        _backImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _backImageView.backgroundColor = [UIColor clearColor];
    }
    return _backImageView;
}

- (UIImageView *)iconImageView {
    if (!_iconImageView) {
        _iconImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _iconImageView.backgroundColor = [UIColor clearColor];
        _iconImageView.image = [UIImage imageNamed:@"ic_appmain_boardcast"];
    }
    return _iconImageView;
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _titleLabel.font = DFRegularFontSize(14);
        _titleLabel.textColor = [UIColor colorWithHexString:@"666666"];
        _titleLabel.backgroundColor = [UIColor clearColor];
        _titleLabel.textAlignment = NSTextAlignmentLeft;
        _titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
    }
    return _titleLabel;
}

- (UIButton *)showButton {
    if (!_showButton) {
        _showButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _showButton.backgroundColor = [UIColor colorWithHexString:@"fd6230"];
        _showButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
        _showButton.titleLabel.font = DFRegularFontSize(12);
        [_showButton setTitleColor:[UIColor colorWithHexString:@"ffffff"] forState:UIControlStateNormal];
        _showButton.layer.cornerRadius = kShowButtonHeight/2;
        _showButton.layer.borderWidth = 1.0;
        _showButton.layer.borderColor = [UIColor colorWithHexString:@"fd6230"].CGColor;
        _showButton.layer.masksToBounds = YES;
        [_showButton addTarget:self action:@selector(showButtonAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _showButton;
}

- (void)dealloc {
    
}

@end

五、使用轮播展示信息

由于我的界面整体是一个UITableView,我这边在DFAppMainPageBoardCastCell使用轮播播放控件。

DFAppMainPageBoardCastCell.h

#import <UIKit/UIKit.h>
#import "DFAppMainPageCastContentView.h"
#import "DFAppMainPageBoardCastModel.h"
#import "DFAppMainPageCastContentCell.h"

@interface DFAppMainPageBoardCastCell : UITableViewCell

@property (nonatomic, strong) NSMutableArray *boardCastList;

+ (CGFloat)showCellHeight;

@end

DFAppMainPageBoardCastCell.m

#import "DFAppMainPageBoardCastCell.h"

static CGFloat kShowCellHeight = 50.0;

static CGFloat kShowCastHeight = 40.0;

static CGFloat kHBGPadding = 15.0;
static CGFloat kVBGPadding = 5.0;

@interface DFAppMainPageBoardCastCell ()<DFAppMainPageCastContentDelegate, DFAppMainPageCastContentDataSource>

@property (nonatomic, strong) NSMutableArray *broadCastItems;
@property (nonatomic, strong) NSMutableArray *bcastItems;

@property (nonatomic, strong) UIImageView *backImageView;
@property (nonatomic, strong) DFAppMainPageCastContentView *castContentView;

@end

@implementation DFAppMainPageBoardCastCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        
        self.backgroundColor = [UIColor clearColor];
        self.contentView.backgroundColor = [UIColor whiteColor];
        
        [self.contentView addSubview:self.backImageView];
        [self.backImageView addSubview:self.castContentView];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.backImageView.frame = CGRectMake(kHBGPadding, kVBGPadding, CGRectGetWidth(self.bounds) - 2*kHBGPadding, CGRectGetHeight(self.bounds) - 2*kVBGPadding);
    
    self.castContentView.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.backImageView.frame), CGRectGetHeight(self.backImageView.frame));
}

- (void)setBoardCastList:(NSMutableArray *)boardCastList {
    _boardCastList = boardCastList;
    NSMutableArray *broads = [NSMutableArray arrayWithCapacity:0];
    for (NSInteger i = 0; i < boardCastList.count; i++) {
        DFAppMainPageBoardCastModel *model = [boardCastList objectAtIndex:i];
        DFAppMainPageCastContentItem *item = [[DFAppMainPageCastContentItem alloc] init];
        item.aIndex = [NSString stringWithFormat:@"%ld",(long)(i+1)];
        item.extObject = model;
        [broads addObject:item];
    }
    self.bcastItems = broads;
    
    [self setBroadcastItems];
    [self.castContentView reloadBroadcastData];
    [self.castContentView scrollViewByIndex:0];
    // self.castView.pageNumber = self.castItems.count;
    // self.castView.showPageDot = (self.broadCastItems.count > 1);
    self.castContentView.showPageDot = NO;
}

#pragma mark - Broadcast显示控件
/**
 设置item数据源
 
 @return 数据源
 */
- (NSArray *)itemsForBroadcast {
    return self.broadCastItems;
}

/**
 数据源指定的子控件
 
 @param indexPath 索引
 @return 子控件
 */
- (UITableViewCell *)cellForBroadcast:(UITableView *)tableView atIndex:(NSIndexPath *)indexPath {
    
    static NSString *identifier = @"DFAppMainPageCastContentCell";
    DFAppMainPageCastContentCell *cell = (DFAppMainPageCastContentCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[DFAppMainPageCastContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    DFAppMainPageCastContentItem *item = self.broadCastItems[indexPath.row];
    
    DFAppMainPageBoardCastModel *model = (DFAppMainPageBoardCastModel *)item.extObject;
    
    cell.showModel = model;

    return cell;
}

/**
 点击的当前界面
 
 @param index 下标
 */
- (void)broadcastDidSelectItem:(NSInteger)index {
    DFAppMainPageCastContentItem *item = self.broadCastItems[index];
    NSLog(@"item:%@",item);
}

- (void)setBroadcastItems {
    
    //添加最后一张图 用于循环
    NSInteger length = self.bcastItems.count;
    NSMutableArray *itemBroadcastArray = [NSMutableArray arrayWithCapacity:length+2];
    if (length > 1) {
        DFAppMainPageCastContentItem *model = [self.bcastItems objectAtIndex:length-1];
        [itemBroadcastArray addObject:model];
    }
    
    for (int i = 0; i < length; i++) {
        DFAppMainPageCastContentItem *model = [self.bcastItems objectAtIndex:i];
        [itemBroadcastArray addObject:model];
    }
    
    //添加第一张图 用于循环
    if (length > 1) {
        DFAppMainPageCastContentItem *model = [self.bcastItems objectAtIndex:0];
        [itemBroadcastArray addObject:model];
    }
    
    self.broadCastItems = itemBroadcastArray;
}


+ (CGFloat)showCellHeight {
    return kShowCellHeight;
}

#pragma mark - LAZY
- (UIImageView *)backImageView {
    if (!_backImageView) {
        _backImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _backImageView.backgroundColor = [UIColor colorWithHexString:@"f7f8ff"];
        _backImageView.userInteractionEnabled = YES;
        _backImageView.layer.cornerRadius = (kShowCellHeight - 2*kVBGPadding)/2.0;
        _backImageView.layer.masksToBounds = YES;
    }
    return _backImageView;
}

- (DFAppMainPageCastContentView *)castContentView {
    if (!_castContentView) {
        _castContentView = [[DFAppMainPageCastContentView alloc] initWithFrame:CGRectMake(0.0, 0.0, (kScreenWidth - 2*kHBGPadding)/2.0, kShowCastHeight) isAutoPlay:YES];
        _castContentView.backgroundColor = [UIColor clearColor];
        _castContentView.frame = CGRectMake(0.0, 0.0, (kScreenWidth - 2*kHBGPadding)/2.0, kShowCastHeight);
        _castContentView.delegate = self;
        _castContentView.dataSource = self;
        _castContentView.clipsToBounds = YES;
    }
    return _castContentView;
}

@end

六、小结

iOS开发-实现上下翻转轮播循环信息播报效果。实现定时器设置偏移量contentOffset。

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/811472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux多线程】线程的互斥与同步(附抢票案例代码+讲解)

线程的互斥与同步 &#x1f4ab; 概念引入⭐️临界资源&#xff08;Critical Resource&#xff09;&#xff1a;&#x1f31f;临界区&#xff08;Critical Section&#xff09;&#xff1a;✨互斥&#xff08;Mutex&#xff09;&#xff1a; ⚡️结合代码看互斥☄️ 代码逻辑&a…

无涯教程-jQuery - Progressbar组件函数

小部件进度条功能可与JqueryUI中的小部件一起使用。一个简单的进度条显示有关进度的信息。一个简单的进度条如下所示。 Progressbar - 语法 $( "#progressbar" ).progressbar({value: 37 }); Progressbar - 示例 以下是显示进度条用法的简单示例- <!doctype …

appium的基本使用

appium的基本使用 一、appium的基本使用appium环境安装1、安装Android SDK 2、安装Appium3、安装手机模拟器4、Pycharm安装 appium-python-alicent5、连接appium和模拟器6、Python代码调用appium软件&#xff0c;appium软件在通过adb命令调用android操作系统&#xff08;模拟器…

如何在局域网外SSH远程访问连接到家里的树莓派?

文章目录 如何在局域网外SSH远程访问连接到家里的树莓派&#xff1f;如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar4.2 cpolar进行token认证4.3 配置cpol…

详解Mybatis之分页插件【PageHelper】

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 文章目录 一. 什么是分页&#xff1f;二. 为什么使用分页&#xff1f;三. 如何设计一个Page类&#xff08;分…

【Python】Web学习笔记_flask(1)——getpost

flask提供的request请求对象可以实现获取url或表单中的字段值 GET请求 从URL中获取name、age两个参数 from flask import Flask,url_for,redirect,requestappFlask(__name__)app.route(/) def index():namerequest.args.get(name)agerequest.args.get(age)messagef姓名:{nam…

玩转LaTeX(四)【文献引入、自命令】

参考文献BibTeX: 使用最原始的文献导入&#xff1a;&#xff08;正文区&#xff09; \begin{document}%参考文献bibtex %一次管理一次使用 %参考文献格式&#xff1a; %\begin{thebibliography}{编号样本} % \bibitem[记号]{引用标志}文献条目1 % \b…

Java 程序员:本是为了跳槽刷完 1000 道真题,想不到被老板知道直接给我升职

同事&#xff1a;前阵子听说你要跳槽&#xff0c;现在准备得怎么样啊&#xff1f; 程序员 T&#xff1a;不跳了 同事&#xff1a;啊&#xff1f;为什么&#xff1f; 程序员 T&#xff1a;涨薪了呗&#xff1f; 同事&#xff1a;真的吗&#xff1f;涨了多少&#xff1f;你自…

IT类技术面试:从小白到高手的进阶指南

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

ElasticSearch基础篇-Java API操作

ElasticSearch基础-Java API操作 演示代码 创建连接 POM依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sch…

golang interface类型的nil

golang中interface变量&#xff0c;底层两个对象来存&#xff0c;一个是type、一个是value&#xff0c;只有type、value都为nil时&#xff0c;interface变量才是nil package mainimport ("fmt""reflect" )type People interface {Show() }type Student str…

(杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(4)

1003 Simple Set Problem 双指针的思想,双端队列 先从小到大排个序 一个一个放到双端队列里,一边放一边维护集合个数为k个 利用滑动窗口,当滑动窗口中集合个数为k时,只需算出滑动窗口最后一个数减去第一个数,然后每次取min就行了 AC代码&#xff1a; #include<iostream>…

电子元器件选型与实战应用—专栏介绍

文章目录 背景专栏内容专栏特色学习收获适用人群 背景 大家好&#xff0c;我是记得诚。 我新开了一个专栏&#xff0c;名字叫《电子元器件选型与实战应用》&#xff0c;选取20个最常用的电子元器件。 这是一个只讲如何选型&#xff0c;在实际电路中如何应用的专栏。 作为硬…

软考A计划-系统集成项目管理工程师-项目采购管理-上

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

机器学习笔记之优化算法(四)线搜索方法(步长角度;非精确搜索)

机器学习笔记之优化算法——线搜索方法[步长角度&#xff0c;非精确搜索] 引言回顾&#xff1a;精确搜索步长及其弊端非精确搜索近似求解最优步长的条件反例论述 引言 上一节介绍了从精确搜索的步长角度观察了线搜索方法&#xff0c;本节将从非精确搜索的步长角度重新观察线搜…

flask 点赞系统

dianzan.html页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>点赞系统</title> </head> <body><h2>这是一个点赞系统</h2><table border"1"><…

非线性优化的数值方法小结——梯度下降法,牛顿法,高斯牛顿法,LM法

非线性优化的数值方法小结——梯度下降法&#xff0c;牛顿法&#xff0c;高斯牛顿法&#xff0c;LM法 在非线性优化领域中&#xff0c;我们常采用一系列数值方法对构造的问题进行求解&#xff0c;各方法彼此联系&#xff0c;本文将对这些数值处理方法进行梳理构造。 问题描述…

Win系统如何下载安装使用cpolar内网穿透工具?

文章目录 概述什么是cpolar&#xff1f;cpolar可以用在哪些场景&#xff1f; 1. 注册cpolar帐号1.1 访问官网站点&#xff1a;[https://www.cpolar.com](https://link.zhihu.com/?targethttps%3A//www.cpolar.com/) 1.2 注册帐号 2. 下载Windows版本cpolar客户端2.1 下载并安装…

Vue.js 生命周期函数

系列文章目录 Vue.js基础简答题 文章目录 系列文章目录前言一、创建阶段1.beforeCreate2.created3.beforeMount4.mounted 二、运行阶段1.beforeUpdate2.updated 三、销毁阶段1.beforeDestroy2.destroyed 总结 前言 Vue.js 生命周期指的是Vue实例的生命周期&#xff1b; Vue实…

深入学习 Redis - 基于 Jedis 通过 Java 客户端操作 Redis

目录 一、Jedis 依赖 二、Java 客户端操控 redis 2.1、准备工作&#xff08;ssh 隧道&#xff09; 2.2、概要 2.2、string 2.3、hash 2.4、list 2.5、set 2.5、zset 一、Jedis 依赖 自己去 中央仓库 上面找. 二、Java 客户端操控 redis 2.1、准备工作&#xff08;ssh 隧…