tableview列表中的cell单元格有倒计时的情况处理
来源:互联网 发布:软件培训班西安 编辑:程序博客网 时间:2024/06/05 22:01
在项目开发中遇到在tableiview列表中的cell单元格要使用到倒计时功能,当处理不当时,即cell复用没使用好时,会出现倒计时显示异常。比如说第一个cell显示且倒计时开始后,当tableview列表向上滚动,即第一个cell向上移动且移出屏幕,然后tableview列表再向下滚动,即第一个cell向下移动且又在屏幕显示,这个时候你会发现倒计时又是从头开始计时了。
为了避免这种情况的产生,在编码过程中我们只需要这样考虑,并这样做就可以了
步骤1 自定义cell
1-1 在自定义cell中创建NSTimer进行倒计时(将每个cell中的倒计时在当前cell中进行)
1-2 在自定义cell中设置可以获取该NSTimer的方法(便于对NSTimer计时器的释放处理)
步骤2 在tableview列表所在视图viewcontroller中定义四变量
2-1 变量1 NSTimer(设置为当前视图中的计时器,用于进行倒计时计算时间间隔差)
2-2 变量2 NSMutableArray(用于保存每个计时器,便于当前视图释放时,处理计时器)
2-3 变量3 NSInteger(当前时间点,与变量4计算时间间隔差)
2-4 变量4 NSInteger(变化时间点,在变量1中进行自减,即倒计时计算;同时与变量3计算时间变化间隔差)
步骤3 使用
3-1 在tableview中使用
3-1-1 在cellForRow方法中执行自定义cell的倒计时方法
3-1-2 在cellForRow方法中获取自定义cell的计时器并保存在NSMutableArray中
3-2 在viewcontroller视图中使用
3-2-1 在viewWillDisapper方法中释放保存有计时器的数组
详见代码
1 自定义cell代码
1-1 .h文件
#import <UIKit/UIKit.h>@interface CountDownCell : UITableViewCell{ @private UILabel *label; NSTimer *coundTimer; //计时器 NSInteger currentTime; //计时时间,秒}///开始计时- (void)coundDownStart:(NSInteger)time;///释放计时器- (void)releaseTimer;///获取计时器,便于释放计时器- (NSTimer *)getCellTimer;@end
1-2 .m文件
#import "CountDownCell.h"@implementation CountDownCell- (void)awakeFromNib { // Initialization code}- (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state}- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; label = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 0.0, self.frame.size.width - 10.0 * 2, self.frame.size.height)]; [self addSubview:label]; } return self;}- (void)dealloc{ coundTimer = nil; NSLog(@"cell timer %@", coundTimer);}//开始计时- (void)coundDownStart:(NSInteger)time{ currentTime = time; [self show]; if (!coundTimer) { coundTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(coundDown:) userInfo:nil repeats:YES]; }}- (void)coundDown:(NSTimer *)timer{ currentTime--; [self show];}- (void)show{ NSInteger day = currentTime / (24 * 60 * 60); NSInteger hour = (currentTime % (24 * 60 * 60)) / (60 * 60); NSInteger minute = ((currentTime % (24 * 60 * 60)) % (60 * 60)) / 60; NSInteger second = ((currentTime % (24 * 60 * 60)) % (60 * 60)) % 60; NSString *time = [NSString stringWithFormat:@"%d天%d时%d分钟%d秒", day, hour, minute, second]; NSString *timeStr = [NSString stringWithFormat:@"倒计时:%@", time]; label.text = timeStr;}//释放计时器- (void)releaseTimer{ if (coundTimer) { if ([coundTimer isValid]) { [coundTimer invalidate]; coundTimer = nil; } }}///获取计时器- (NSTimer *)getCellTimer{ return coundTimer;}@end
2 viewcontroller代码
2-1 .h文件
#import <UIKit/UIKit.h>@interface TableCountdownVC : UIViewController@end
2-2 .m文件
#import "TableCountdownVC.h"#import "CountDownCell.h"@interface TableCountdownVC () <UITableViewDataSource, UITableViewDelegate>@property (nonatomic, strong) UITableView *mainTableView;@property (nonatomic, strong) NSMutableArray *mainArray;@property (nonatomic, strong) NSMutableArray *timerArray; //存储timer数组,便于释放计时器@property (nonatomic, strong) NSTimer *mainTimer; //计时器,控制计时间隔@property (nonatomic, assign) NSTimeInterval sourceTime; //时间初始点,与currtentTime的时间差为变化时间间隔@property (nonatomic, assign) NSTimeInterval currtentTime;//时间变化后时点,与sourceTime的时间差为变化时间间隔@end@implementation TableCountdownVC- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.title = @"cell倒计时复用"; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"reload" style:UIBarButtonItemStyleDone target:self action:@selector(buttonClick:)]; [self setlocalData]; [self setUI];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}- (void)loadView{ [super loadView]; self.view.backgroundColor = [UIColor whiteColor];}- (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self killTimer];}- (void)dealloc{ self.mainTimer = nil; NSLog(@"timer %@", self.mainTimer);}#pragma mark -创建视图- (void)setUI{ if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { [self setEdgesForExtendedLayout:UIRectEdgeNone]; } self.mainTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain]; [self.view addSubview:self.mainTableView]; self.mainTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.mainTableView.backgroundColor = [UIColor lightTextColor]; self.mainTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; self.mainTableView.delegate = self; self.mainTableView.dataSource = self;}#pragma mark -数据- (void)setlocalData{ if (self.mainArray) { [self.mainArray removeAllObjects]; } else { self.mainArray = [NSMutableArray array]; } NSDate *date = [NSDate date]; self.currtentTime = [date timeIntervalSinceReferenceDate]; self.sourceTime = self.currtentTime; for (int i = 0; i < 30; i++) { NSInteger time = arc4random() % (int)self.currtentTime + 1000; NSNumber *timeNumber = [NSNumber numberWithInteger:time]; [self.mainArray addObject:timeNumber]; } if (!self.timerArray) { self.timerArray = [NSMutableArray array]; } else { [self killTimer]; } if (self.mainTimer) { [self.mainTimer invalidate]; self.mainTimer = nil; } self.mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(coundDown:) userInfo:nil repeats:YES]; [self.timerArray addObject:self.mainTimer];}- (void)killTimer{ if (self.timerArray) { for (NSTimer *subTimer in self.timerArray) { if (subTimer) { [subTimer invalidate]; } } [self.timerArray removeAllObjects]; }}#pragma mark -响应事件- (void)buttonClick:(UIButton *)button{ [self setlocalData]; [self.mainTableView reloadData];}- (void)coundDown:(NSTimer *)timer{ self.currtentTime--;}#pragma mark -列表视图- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.mainArray.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *const reuseCell = @"reuseCell"; CountDownCell *cell = (CountDownCell *)[tableView dequeueReusableCellWithIdentifier:reuseCell]; if (!cell) { cell = [[CountDownCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseCell]; } NSNumber *timeNumber = [self.mainArray objectAtIndex:indexPath.row]; NSInteger time = timeNumber.integerValue; time = time - (self.sourceTime - self.currtentTime); [cell coundDownStart:time]; NSTimer *cellTimer = [cell getCellTimer]; [self.timerArray addObject:cellTimer]; return cell;}- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES];}@end
- tableview列表中的cell单元格有倒计时的情况处理
- iOS之tableView中的静态cell(静态单元格)
- 如何处理一个tableView中同种model多种cell相同逻辑的情况?
- TableView 第一个cell距离tableView的顶端有一段距离
- 获取tableview中的cell
- TableView的顶部有一部分空白区域,不是Cell
- tableview cell的移动
- 如何处理Tableview中cell的单选问题
- iOS在cell中使用倒计时的处理方法
- iOS 在cell中使用倒计时的处理方法(新)
- TableView中的cell不可点击
- 一个tableView的Cell中有两个点击按钮及tableView的重用
- iOS 设置cell的在tableView中的间隔距离
- tableview 自定义cell 点击cell改变cell中的label.text的字体颜色,cell复用出现问题
- tableview 自定义cell 点击cell改变cell中的label.text的字体颜色,cell复用出现问题
- iOS之如何处理TableView cell内容不一致以及cell复用重叠的问题
- 点击tableView的cell弹出tableView
- ios tableView 的cell打开收起功能,类似QQ中的cell折叠功能
- poj1163 the triangle 题解
- HDUOJ - 2054 A == B ?
- bitnami redmine 安装插件
- iOS开发- SceneKit
- Struts2中action获取request、response、session的方式
- tableview列表中的cell单元格有倒计时的情况处理
- UIActivityViewController的使用(Swift实现)
- HDU - 1011(树形dp 背包类型的做法)
- java中this.static.final关键字的定义
- maven POM.xml 标签详解
- hdu2110
- [ACM] hdu 5147 Sequence II (树状数组,前缀和,后缀和)
- react.js:实例教程不工作
- poj2389