Github的完整项目源码:https://github.com/FourOnes/seckill
在某些场景, 可能大部分在电商系统中,iOS端应用需要使用UITableView展示从后端拉取的商品(活动)数据信息,包括名称、图片、以及截止时间等。
当前需要在每一个商品(活动)后面加一个时间倒计时,只有倒计时结束以后,用户才可以点击操作。比如在抢购商品的时候,一般都会有一个开始时间,在这之前一般都一个倒计时。在这样的情况下,UITableView有可能会展示后端成千上百的数据,如果简单高效的处理每一个商品(活动)的倒计时。
为了简化,只有倒计时结束以后,才可以点击ORDER。
整体思路
如果有一千条数据要展示,不可能为每一个数据开启一个Timer启动倒计时。
每一个产品都有一个截止时间的字段,自定义UITableViewCell,将产品信息绑定到UITableViewCell。然后启动一个间隔周期为1秒的Timer,定期的向外面发送通知,同时UITableViewCell订阅这个通知,根据当前的时间与截止时间,可以计算出还剩余的时间,如果剩余时间为0,则显示ORDER按钮。
这里利用了UITableView的重用机制,比如设备当前可见区域可以显示8个UITableViewCell,那么在整个生命周期中最大存在8个UITableViewCell示例。
核心代码
TimerManager
主要维护一个Timer的启动停止
#import <Foundation/Foundation.h>
extern NSString * const timerManagerNotify;
@interface TimerManager : NSObject
+(TimerManager *)manager;
-(void)start;
-(void)stop;
@end
#import "TimerManager.h"
static TimerManager *staticTimeManager;
NSString * const timerManagerNotify = @"com.limingru.timermanager";
@interface TimerManager()
@property(nonatomic,strong)NSTimer *timer;
@end
@implementation TimerManager
+(TimerManager *)manager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
staticTimeManager = [TimerManager new];
});
return staticTimeManager;
}
-(void)start {
if (self.timer) return;
self.timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
-(void)stop {
[self.timer invalidate];
self.timer.fireDate = [NSDate distantFuture];
self.timer = nil;
}
-(void)timerAction {
NSLog(@"TimerManager timerAction");
[[NSNotificationCenter defaultCenter] postNotificationName:timerManagerNotify object:nil];
}
@end
MyUITableViewCell
自定义的UITableViewCell,主要订阅TimerManager发布的通知,更新界面
#import <UIKit/UIKit.h>
#import "Product.h"
@interface MyUITableViewCell : UITableViewCell
@property(nonatomic,strong)Product *product;
@end
#import "MyUITableViewCell.h"
#import "TimerManager.h"
@interface MyUITableViewCell()
@property (weak, nonatomic) IBOutlet UIButton *goBtn;
@property (weak, nonatomic) IBOutlet UILabel *statusLbl;
@property (weak, nonatomic) IBOutlet UILabel *timerLbl;
@end
@implementation MyUITableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self.goBtn setTitle:@"ORDER" forState:UIControlStateNormal];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(timeNotify:) name:timerManagerNotify object:nil];
}
-(void)setProduct:(Product *)product {
_product = product;
self.timerLbl.hidden = self.goBtn.hidden = YES;
self.statusLbl.text = _product.name;
[self checkTime];
}
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
NSLog(@"dealloc >> %@",[self class]);
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (IBAction)go:(id)sender {
NSLog(@"%@",[NSString stringWithFormat:@"ORDERED %@",self.product.name]);
}
-(void)timeNotify:(NSNotification *)sender {
[self checkTime];
}
-(void)checkTime {
NSDate *nowDate = [NSDate date];
NSTimeInterval timeInterval = [nowDate timeIntervalSinceReferenceDate];
NSTimeInterval diff = self.product.endTime - timeInterval;
if (diff<=0) {
self.timerLbl.hidden = YES;
self.goBtn.hidden = NO;
return;
}
self.timerLbl.hidden = NO;
self.timerLbl.text = [NSString stringWithFormat:@"%.f",diff];
}
@end
完整源码地址
附上Github的完整项目源码:https://github.com/FourOnes/seckill