Github的完整項(xiàng)目源碼:https://github.com/FourOnes/seckill
在某些場(chǎng)景, 可能大部分在電商系統(tǒng)中恼琼,iOS端應(yīng)用需要使用UITableView展示從后端拉取的商品(活動(dòng))數(shù)據(jù)信息,包括名稱刃永、圖片垛膝、以及截止時(shí)間等。
當(dāng)前需要在每一個(gè)商品(活動(dòng))后面加一個(gè)時(shí)間倒計(jì)時(shí)摊求,只有倒計(jì)時(shí)結(jié)束以后邓了,用戶才可以點(diǎn)擊操作毡泻。比如在搶購商品的時(shí)候胜茧,一般都會(huì)有一個(gè)開始時(shí)間,在這之前一般都一個(gè)倒計(jì)時(shí)仇味。在這樣的情況下呻顽,UITableView有可能會(huì)展示后端成千上百的數(shù)據(jù),如果簡(jiǎn)單高效的處理每一個(gè)商品(活動(dòng))的倒計(jì)時(shí)丹墨。
為了簡(jiǎn)化芬位,只有倒計(jì)時(shí)結(jié)束以后,才可以點(diǎn)擊ORDER带到。
整體思路
如果有一千條數(shù)據(jù)要展示,不可能為每一個(gè)數(shù)據(jù)開啟一個(gè)Timer啟動(dòng)倒計(jì)時(shí)英染。
每一個(gè)產(chǎn)品都有一個(gè)截止時(shí)間的字段揽惹,自定義UITableViewCell,將產(chǎn)品信息綁定到UITableViewCell四康。然后啟動(dòng)一個(gè)間隔周期為1秒的Timer搪搏,定期的向外面發(fā)送通知,同時(shí)UITableViewCell訂閱這個(gè)通知闪金,根據(jù)當(dāng)前的時(shí)間與截止時(shí)間疯溺,可以計(jì)算出還剩余的時(shí)間,如果剩余時(shí)間為0哎垦,則顯示ORDER按鈕囱嫩。
這里利用了UITableView的重用機(jī)制,比如設(shè)備當(dāng)前可見區(qū)域可以顯示8個(gè)UITableViewCell漏设,那么在整個(gè)生命周期中最大存在8個(gè)UITableViewCell示例墨闲。
核心代碼
TimerManager
主要維護(hù)一個(gè)Timer的啟動(dòng)停止
#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發(fā)布的通知郑口,更新界面
#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的完整項(xiàng)目源碼:https://github.com/FourOnes/seckill