一、簡單介紹
在UITableViewCell中每條數據中顯示該內容的倒計時, 並隨時間進行倒數,這是很多電商app最常見的活動推銷功能模塊,自然想到用的就是計時器了。
二、基本想法
想法1:在每個cell中添加NSTimer, 負責對cell的倒數
出現的問題: cell有重用機制,每次重用時數據不好處理, 而且每個cell的倒數數不同, 需要在重用時對NSTimer進行廢除並重新開啟, 如果顯示的cell數量過多, 需要創建很多的NSTimer對象。
想法2:在模型中添加NSTimer, 負責對數據進行倒計數
出現的問題:與想法1一樣, 因為cell重用, 以及數據數量導致出現一樣的問題。
三、最佳方案
創建倒計時管理類, 擁有一個時間差屬性, 並且每秒對時間差進行加1的操作,並發出一個通知; 而每個cell都監聽這個通知, 在通知回調中, 將服務器返回的剩余時間減去時間差再進行格式化顯示即可.
好處: 全局只需要一個NSTimer對象, 沒有耦合性, 不需要對NSTimer作過多的操作。
四、實現效果
五、使用方法
1. 導入"OYCountDownManager.h"
2. 在第一次使用的地方調用[kCountDownManager start]核心代碼:
- (void)viewDidLoad { [super viewDidLoad]; // 啟動倒計時管理 [kCountDownManager start]; }
3. 在Cell中監聽通知 kCountDownNotification
- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 監聽通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(countDownNotification) name:kCountDownNotification object:nil]; } return self; }
4. 在cell設置通知回調, 取得時間差, 根據時間差進行處理
/// 計算倒計時
NSInteger countDown = [self.model.count integerValue] - kCountDownManager.timeInterval;
if (countDown < 0){
// 倒計時結束時回調
xxxx(使用代理或block)
} return; /// 重新賦值 self.timeLabel.text = [NSString stringWithFormat:@"倒計時zd:zd:zd", countDown/3600, (countDown/60)%60, countDown%60];
5. 當刷新數據時,調用[kCountDownManager reload]
- (void)reloadData { // 網絡加載數據 // 調用[kCountDownManager reload] [kCountDownManager reload]; // 刷新 [self.tableView reloadData]; }
6. 當不需要倒計時時, 廢除定時器
[kCountDownManager invalidate];
六、注意事項
(1)滾動cell時出去文字閃爍,在給cell的模型賦值后, 最好手動調用一下countDownNotification方法, 保證及時刷新
/// 重寫setter方法 - (void)setModel:(Model *)model { _model = model; self.titleLabel.text = model.title; // 手動調用通知的回調 [self countDownNotification]; }
(2)倒計時為0后出現復用問題,在倒計時為0后, 應該回調給控制器, 從后台請求一次數據, 保證倒計時沒有出現誤差
if (countDown <= 0) { // 倒計時結束時回調 xxxx(使用代理或block) }return;
七、完整代碼
github: GitHub-herobin22/OYCountDownManger
八、附注
原文作者:大頭herob
本文轉載自簡書: http://www.jianshu.com/p/af62a56ef7e2