iOS工具類-OC篇

最近想整理下關(guān)于OC的工具類,常用到的也方便自己之后查閱,也可以給需要的朋友參考。

1、兩種倒計(jì)時(shí)

  • 第一種:GCD
__block NSInteger timeout = time;//可以假設(shè)time等于60秒
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
    dispatch_source_set_event_handler(_timer, ^{
        if(timeout<=0){ //倒計(jì)時(shí)結(jié)束,關(guān)閉
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //主線程中處理UI
            });
        }else{
            dispatch_async(dispatch_get_main_queue(), ^{
                //主線程中處理UI
                presellTimeLB.text = [self dateFormatDays_Hours_MinsWith:timeout];
            });
            timeout--;
        }
    });
    dispatch_resume(_timer);

這里我假設(shè)我有一個(gè)名為presellTimeLB的Label,處理倒計(jì)時(shí)的方法dateFormatDays_Hours_MinsWith: (僅供參考)

 - (NSString *)dateFormatDays_Hours_MinsWith:(NSInteger)time
{
    NSInteger days = 0,hours = 0,minutes = 0,second = 0;
    NSInteger daySeconds = 24*60*60;
    //獲取天數(shù)
    if (time >= daySeconds) {
        days = time/daySeconds;
        time = time%daySeconds;
    }
    //獲取小時(shí)數(shù)
    if(time>=60*60){
        hours = time/3600;
        time = time%3600;
    }
    //獲取分鐘數(shù)
    if (time>=60) {
        minutes = time/60;
        time = time%60;
    }
    //獲取秒數(shù)
    second = time;
    if (days>0) {
        return [NSString stringWithFormat:@"%ld天%ld時(shí)%ld分",(long)days,(long)hours,(long)minutes];
    }else{
        return [NSString stringWithFormat:@"%ld時(shí)%ld分%ld秒",(long)hours,(long)minutes,(long)second];
    }
}
  • 第二種:NSTimer

1)聲明

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];

2)實(shí)現(xiàn)select方法

 - (void)timerFireMethod:(NSTimer *)theTimer
{
    timer = theTimer;
    static NSInteger hhh;
    if (timeStart) {
        hhh = [self.leftTime integerValue];
        timeStart = NO;
    }
    if (hhh <= 1) {
        preSellView.hidden = YES;
        //注①
        [timer invalidate];
    }else {   
        //注②
        [[NSRunLoop currentRunLoop] addTimer:theTimer forMode:NSRunLoopCommonModes];
        hhh--;
        dispatch_async(dispatch_get_main_queue(), ^{
            [presellTimeLB setText:[self dateFormatDays_Hours_MinsWith:hhh]];
        });
    }
}

注:
NSTimer對(duì)象用完之后必須進(jìn)行invalidateNSTimer才會(huì)消失。比如說(shuō)你還需要考慮到倒計(jì)時(shí)沒(méi)結(jié)束時(shí)退出當(dāng)前頁(yè)面時(shí)是不是也需要把當(dāng)前的NSTimer invalidate呢?
②這里為什么要用NSRunLoop寫這句代碼呢?如果沒(méi)有這句代碼,會(huì)發(fā)現(xiàn)在界面上滾動(dòng)一個(gè)scrollView,那么滾動(dòng)停止前,timer像是暫停了一樣,其實(shí)這是runloop的mode在作怪。
runloop可以理解為cocoa下的一種消息循環(huán)機(jī)制,用來(lái)處理各種消息事件,我們?cè)陂_發(fā)的時(shí)候并不需要手動(dòng)去創(chuàng)建一個(gè)runloop,因?yàn)榭蚣転槲覀儎?chuàng)建了一個(gè)默認(rèn)的runloop,通過(guò)[NSRunloop currentRunloop]我們可以得到一個(gè)當(dāng)前線程下面對(duì)應(yīng)的runloop對(duì)象,不過(guò)我們需要注意的是不同的runloop之間消息的通知方式。
在開啟一個(gè)NSTimer實(shí)質(zhì)上是在當(dāng)前的runloop中注冊(cè)了一個(gè)新的事件源,而當(dāng)scrollView滾動(dòng)的時(shí)候,當(dāng)前的MainRunLoop是處于UITrackingRunLoopMode的模式下,在這個(gè)模式下,是不會(huì)處理NSDefaultRunLoopMode的消息(因?yàn)镽unLoop Mode不一樣),要
要想在scrollView滾動(dòng)的同時(shí)也響應(yīng)其他runloop的消息,需要改變兩者之間的runloopMode.

[[NSRunLoop currentRunLoop] addTimer:theTimer forMode:NSRunLoopCommonModes];
  • NSTimer 的另一種寫法
  - (void)timerFireMethod:(NSTimer *)theTimer
{
    NSCalendar *cal = [NSCalendar currentCalendar];//定義一個(gè)NSCalendar對(duì)象
    NSDateComponents *endTime = [[NSDateComponents alloc] init];    //初始化目標(biāo)時(shí)間...
    NSDate *today = [NSDate date];    //得到當(dāng)前時(shí)間
    NSDate *date = [NSDate dateWithTimeInterval:80 sinceDate:today];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *dateString = [dateFormatter stringFromDate:date];
    static int year;
    static int month;
    static int day;
    static int hour;
    static int minute;
    static int second;
    if(timeStart) {//從NSDate中取出年月日,時(shí)分秒,但是只能取一次
        year = [[dateString substringWithRange:NSMakeRange(0, 4)] intValue];
        month = [[dateString substringWithRange:NSMakeRange(5, 2)] intValue];
        day = [[dateString substringWithRange:NSMakeRange(8, 2)] intValue];
        hour = [[dateString substringWithRange:NSMakeRange(11, 2)] intValue];
        minute = [[dateString substringWithRange:NSMakeRange(14, 2)] intValue];
        second = [[dateString substringWithRange:NSMakeRange(17, 2)] intValue];
        timeStart= NO;
    }
    [endTime setYear:year];
    [endTime setMonth:month];
    [endTime setDay:day];
    [endTime setHour:hour];
    [endTime setMinute:minute];
    [endTime setSecond:second];
    NSDate *todate = [cal dateFromComponents:endTime]; //把目標(biāo)時(shí)間裝載入date
    //用來(lái)得到具體的時(shí)差,是為了統(tǒng)一成北京時(shí)間
    unsigned int unitFlags = NSYearCalendarUnit| NSMonthCalendarUnit| NSDayCalendarUnit| NSHourCalendarUnit| NSMinuteCalendarUnit| NSSecondCalendarUnit;
    NSDateComponents *d = [cal components:unitFlags fromDate:today toDate:todate options:0];
    NSString *h = [NSString stringWithFormat:@"%ld",(long)[d hour]];
    
    NSString *fen = [NSString stringWithFormat:@"%ld", (long)[d minute]];
    if([d minute] < 10) {
        fen = [NSString stringWithFormat:@"%ld",[d minute]];
    }
    NSString *miao = [NSString stringWithFormat:@"%ld", (long)[d second]];
    if([d second] < 10) {
        miao = [NSString stringWithFormat:@"0%ld",(long)[d second]];
    }
    if([d second] >= 0) {
        //計(jì)時(shí)尚未結(jié)束,do_something
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSRunLoop currentRunLoop] addTimer:theTimer forMode:NSRunLoopCommonModes];
            [presellTimeLB setText:[NSString stringWithFormat:@"%ld時(shí)%ld分%ld秒",[h integerValue],[fen integerValue], [miao integerValue]]];
        });
    } else{
        //倒計(jì)時(shí)結(jié)束,do something
        [theTimer invalidate];
    }
}

注:這里我們以80秒倒計(jì)時(shí)為例,還是假設(shè)我有一個(gè)BOOL類型的timeStart為了取一次原始時(shí)間,有名為presellTimeLB的Laber,nsrunloop改變mode的狀態(tài)照樣寫上。這里把時(shí)間處理和邏輯判斷寫在了一起。

2、字符串富文本處理之NSMutableAttributedString

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容