iOS 在cell中使用倒計時的處理方法(新)

一.前言

之前的文章iOS 在cell中使用倒計時的處理方法得到大量的支持, 在這先感謝大家的支持. 但是也收到不少人的回復表示不會用, 需要一一解答, 由于之前寫的時候沒有使用Markdown編輯, 所以現(xiàn)在沒法更新之前的文章, 重新寫一份清晰的文章

需求: 每條Cell中顯示倒計時, 并隨時間進行倒數(shù)
語言: Objective-C & Swift
系統(tǒng): iOS
Github地址: OYCountDownManager v2.0
OYCountDownManager-Swift v2.0

二.原理分析

原理分析圖.png

單個列表倒計時.gif

v2.0新增

* 多個列表倒計時
* 多個頁面倒計時
* 分頁列表倒計時
* 后臺模式倒計時
多個列表倒計時.gif
多個頁面倒計時.gif
分頁列表倒計時.gif

三.使用方法

1.1 第一種方法: 使用cocoapods自動安裝

pod 'OYCountDownManager'

1.2 第二種方法

下載示例Demo, 把里面的OYCountDownManager文件夾拖到你的項目中

2. 在第一次使用的地方調用[kCountDownManager start]

- (void)viewDidLoad {
    [super viewDidLoad];

    // 啟動倒計時管理
    [kCountDownManager start];
}

3. 在Cell初始化中監(jiān)聽通知 kCountDownNotification

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // 監(jiān)聽通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(countDownNotification) name:kCountDownNotification object:nil];
    }
    return self;
}

4. 在cell設置通知回調, 取得時間差, 根據(jù)時間差進行處理

- (void)countDownNotification {
    /// 計算倒計時
    NSInteger countDown = [self.model.count integerValue] - kCountDownManager.timeInterval;
    if (countDown <= 0) {
          // 倒計時結束時回調
          xxxx(使用代理或block)
    }return;
    /// 重新賦值
    self.timeLabel.text = [NSString stringWithFormat:@"倒計時%02zd:%02zd:%02zd", countDown/3600,       (countDown/60)%60, countDown%60];
}

5. 當刷新數(shù)據(jù)時,調用reload方法

- (void)reloadData {
    // 網(wǎng)絡加載數(shù)據(jù)

    // 調用[kCountDownManager reload]
    [kCountDownManager reload];
    // 刷新
    [self.tableView reloadData];
}

6. 當不需要倒計時時, 廢除定時器

[kCountDownManager invalidate];

四.高級使用(多列表.多頁面.分頁列表)

增加identifier:標識符, 一個identifier支持一個倒計時源, 有一個單獨的時間差

/** 添加倒計時源 */
- (void)addSourceWithIdentifier:(NSString *)identifier;

/** 獲取時間差 */
- (NSInteger)timeIntervalWithIdentifier:(NSString *)identifier;

/** 刷新倒計時源 */
- (void)reloadSourceWithIdentifier:(NSString *)identifier;

/** 刷新所有倒計時源 */
- (void)reloadAllSource;

/** 清除倒計時源 */
- (void)removeSourceWithIdentifier:(NSString *)identifier;

/** 清除所有倒計時源 */
- (void)removeAllSource;

以一個頁面有兩個獨立的列表為例

1.定義identifier(常量)

NSString *const OYMultipleTableSource1 = @"OYMultipleTableSource1";
NSString *const OYMultipleTableSource2 = @"OYMultipleTableSource2";

2.增加倒計時源

// 增加倒計時源 
[kCountDownManager addSourceWithIdentifier:OYMultipleTableSource1];
[kCountDownManager addSourceWithIdentifier:OYMultipleTableSource2];

3.在cell通知回調中, 通過identifier取得時間差, 根據(jù)時間差進行處理

- (void)countDownNotification {
    /// 判斷是否需要倒計時 -- 可能有的cell不需要倒計時,根據(jù)真實需求來進行判斷
    if (0) {
        return;
    }
    /// 計算倒計時
    OYModel *model = self.model;
    /// 根據(jù)identifier取得時間差, 以OYMultipleTableSource1為例
    NSInteger timeInterval = timeInterval = [kCountDownManager timeIntervalWithIdentifier: OYMultipleTableSource1];
    }
    NSInteger countDown = model.count - timeInterval;
    /// 當?shù)褂嫊r到了進行回調
    if (countDown <= 0) {
        self.detailTextLabel.text = @"活動開始";
        // 倒計時結束時回調
          xxxx(使用代理或block)
        return;
    }
    /// 重新賦值
    self.detailTextLabel.text = [NSString stringWithFormat:@"倒計時%02zd:%02zd:%02zd", countDown/3600, (countDown/60)%60, countDown%60];
}

4. 當刷新數(shù)據(jù)時,調用reloadSourceWithIdentifier:刷新時間差

- (void)reloadData {
    // 網(wǎng)絡加載數(shù)據(jù)

   // 調用reloadSourceWithIdentifier:刷新時間差
   [kCountDownManager reloadSourceWithIdentifier:OYMultiplePageSource1];
    // 刷新
    [self.tableView reloadData];
}

5. 當頁面銷毀, 移除倒計時源, 或者不需要定時器, 廢除定時器

// 移除所有倒計時源
[kCountDownManager removeAllSource];
// 廢除定時器
[kCountDownManager invalidate];

五.注意事項

誤差分析

  • NSTimer可以精確到50-100毫秒,不是絕對準確的,所以使用時間累加的方法時間久了有可能成為時間誤差的來源
  • 為秒為單位觸發(fā)定時器, 當reloadData后, 定時器也許剛好到達觸發(fā)點, 時間差+1, 數(shù)據(jù)剛reload完就馬上-1秒
  • 后臺模式是以進入后臺的本地時間, 及進入前臺的本地時間做差值來計算的, 當用戶手動修改本地時間, 也會成為時間差錯誤的來源之一, 如果能在進入前臺的時間再從服務器取一次數(shù)據(jù), 或者記錄服務器時間而不是本地時間, 也可以避免這一誤差

滾動cell時出去文字閃爍

在給cell的模型賦值后, 最好手動調用一下countDownNotification方法, 保證及時刷新

///  重寫setter方法
- (void)setModel:(Model *)model {
    _model = model;
    self.titleLabel.text = model.title;
    // 手動調用通知的回調
    [self countDownNotification];
}

倒計時為0后出現(xiàn)復用問題

在倒計時為0后, 應該回調給控制器, 從后臺請求一次數(shù)據(jù), 保證倒計時沒有出現(xiàn)誤差

if (countDown <= 0) {
          // 倒計時結束時回調
          xxxx(使用代理或block)
    }return;

出現(xiàn)每秒倒計時減2的問題

1.查看定時器設置是否正確, 或者通知是否監(jiān)聽了兩次
2.在countDownNotification方法中, 是否用[NSDate date]做了某些計算, 因為[NSDate date]為當前時間, 每一秒去取都會比上一秒大一秒, 再加上timeInterval也是一秒加一, 那么就會出現(xiàn)每秒倒計時減2的問題

如果還有不懂的問題, 或者出現(xiàn)其它bug
請查看Demo: Demo
或者給我留言, 喜歡的話, 就給作者一個star

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市煞赢,隨后出現(xiàn)的幾起案子抛计,更是在濱河造成了極大的恐慌,老刑警劉巖照筑,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吹截,死亡現(xiàn)場離奇詭異,居然都是意外死亡凝危,警方通過查閱死者的電腦和手機波俄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來媒抠,“玉大人弟断,你說我怎么就攤上這事∨可” “怎么了阀趴?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苍匆。 經(jīng)常有香客問我刘急,道長,這世上最難降的妖魔是什么浸踩? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任叔汁,我火速辦了婚禮,結果婚禮上检碗,老公的妹妹穿的比我還像新娘据块。我一直安慰自己,他們只是感情好折剃,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布另假。 她就那樣靜靜地躺著,像睡著了一般怕犁。 火紅的嫁衣襯著肌膚如雪边篮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天奏甫,我揣著相機與錄音戈轿,去河邊找鬼。 笑死阵子,一個胖子當著我的面吹牛思杯,可吹牛的內容都是我干的。 我是一名探鬼主播色乾,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼腾么,長吁一口氣:“原來是場噩夢啊……” “哼杈湾!你這毒婦竟也來了解虱?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤漆撞,失蹤者是張志新(化名)和其女友劉穎殴泰,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浮驳,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡悍汛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了至会。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片离咐。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖奉件,靈堂內的尸體忽然破棺而出宵蛀,到底是詐尸還是另有隱情,我是刑警寧澤县貌,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布术陶,位于F島的核電站,受9級特大地震影響煤痕,放射性物質發(fā)生泄漏梧宫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一摆碉、第九天 我趴在偏房一處隱蔽的房頂上張望塘匣。 院中可真熱鬧,春花似錦巷帝、人聲如沸忌卤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埠巨。三九已至历谍,卻和暖如春现拒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背望侈。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工印蔬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脱衙。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓侥猬,卻偏偏與公主長得像例驹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子退唠,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容