iOS日歷搭综、NSCalendar初探(基礎(chǔ)篇)。

城市有我奮斗的青春.jpg

######先說下需求:選擇日期彈出日歷(跟途牛划栓,攜程等差不多就行兑巾。。忠荞。行)

初識(shí)NSCalendar到寫完日歷的感受:

  • 懵+1
  • 什么鬼蒋歌?
  • 如此強(qiáng)大的日歷類
  • 果然利弊都有,雖然很強(qiáng)大委煤,但是極其耗內(nèi)存
  • 一組表情表示寫日歷過程中的心情或者每天的心情(同意的猿/媛點(diǎn)贊):


    我的一天.png

先來(lái)點(diǎn)濕的(很濕很能吹...)

NSCalendar官方API:
NSCalendar objects encapsulate information about systems of reckoning time in which the beginning, length, and divisions of a year are defined. They provide information about the calendar and support for calendrical computations such as determining the range of a given calendrical unit and adding units to a given absolute time

NSCalendar的初始化方法:
常用:

// 可指定日歷的算法
NSCalendar  * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
>// currentCalendar取得的值會(huì)一直保持在cache中,第一次取得以后如果用戶修改該系統(tǒng)日歷設(shè)定堂油,這個(gè)值也不會(huì)改變。
NSCalendar  * calendar = [NSCalendar currentCalendar];
//如果用autoupdatingCurrentCalendar碧绞,那么每次取得的值都會(huì)是當(dāng)前系統(tǒng)設(shè)置的日歷的值府框。 
NSCalendar  * autoupdatingCurrent = [NSCalendar autoupdatingCurrentCalendar];
//- initWithCalendarIdentifier:
 //如果想要用公歷的時(shí)候,就要將NSDateFormatter的日歷設(shè)置成公歷头遭。否則隨著用戶的系統(tǒng)設(shè)置的改變寓免,取得的日期的格式也會(huì)不一樣。
    NSCalendar *initCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setCalendar:initCalendar];

NSCalendar官方API翻譯:

NSCalendar對(duì)象封裝了有關(guān)計(jì)算時(shí)間的系統(tǒng)的信息计维,其中定 義了年的開始袜香,長(zhǎng)度和分割。它們提供關(guān)于日歷的信息和對(duì)日歷計(jì)算的支持鲫惶,例如確定給定的日歷單元的范圍和將單位添加到給定的絕對(duì)時(shí)間

由此能理解數(shù)學(xué)英語(yǔ)都辣雞的我看到它有多懵蜈首,NSCalendar功能很強(qiáng)大,還有一點(diǎn)就是我寫完日歷后欠母,界面會(huì)非郴恫撸卡。最終發(fā)現(xiàn)是這個(gè)NSCalendar特別特別耗內(nèi)存赏淌。最好能寫成全局變量來(lái)使用踩寇。

是時(shí)候來(lái)點(diǎn)干的了(聊一些我工作用到的類和一些封裝的方法)

先上效果圖瞅瞅(類似途牛的日歷,沒有選擇后標(biāo)記):

calendarTop.png

calendarBottom.png

<p>1.獲取當(dāng)前月份有多少天:</p>

-(NSInteger)getCurrentMonthForDays{
    // 創(chuàng)建一個(gè)日期類對(duì)象(當(dāng)前月的calendar對(duì)象)
    NSCalendar *calendar = [NSCalendar currentCalendar];
    // NSRange是一個(gè)結(jié)構(gòu)體六水,其中l(wèi)ocation是一個(gè)以0為開始的index俺孙,length是表示對(duì)象的長(zhǎng)度辣卒。他們都是NSUInteger類型。
    NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[NSDate date]];
    NSUInteger numberOfDaysInMonth = range.length;
   return numberOfDaysInMonth;
}

<p>2獲取目標(biāo)月份的天數(shù):</p>

 -(NSInteger)getNextNMonthForDays:(NSDate)date
{
    NSCalendar * calendar = [NSCalendar currentCalendar];
    // 調(diào)用rangeOfUnit方法:(返回一樣是一個(gè)結(jié)構(gòu)體)兩個(gè)參數(shù)一個(gè)大單位睛榄,一個(gè)小單位(.length就是天數(shù)荣茫,.location就是月)
    NSInteger monthNum = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
    return monthNum;
}

<p>3.獲取一個(gè)目標(biāo)date(包含某個(gè)月的1號(hào)數(shù)據(jù)),或者說獲取某個(gè)月的1號(hào)的date對(duì)象</p>

    -(NSDate *)getAMonthframDate:(NSDate*)date {
    // 指定日歷單位场靴,如日期和月份啡莉。(這里指定了年月日,還有其他字段添加單位.特別齊全 :世紀(jì)旨剥,年月日時(shí)分秒等等等)
    NSCalendarUnit dayInfoUnits  = NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    // NSDateComponents封裝了日期的組件,年月日時(shí)分秒等(個(gè)人感覺像是平時(shí)用的model模型)
    NSDateComponents *components = [calendar components: dayInfoUnits fromDate:date];
    // 指定1號(hào)
    components.day = 1;
    // 指定月份(我這里是獲取當(dāng)前月份的下1個(gè)月的1號(hào)的date對(duì)象,所以用的++咧欣,其上個(gè)月或者其他同理)
    components.month++;
    // 轉(zhuǎn)成需要的date對(duì)象return
    NSDate * nextMonthDate =[calendar dateFromComponents:components];
    return nextMonthDate;
}
(用到的API基本注釋完了下邊就不那么多注釋了)純屬個(gè)人理解泞边,如發(fā)現(xiàn)錯(cuò)誤的地方請(qǐng)指正该押,大家共同進(jìn)步.

<p>
</p>
<p>4.獲取某個(gè)月的1號(hào)是星期幾(必不可少的一個(gè)方法,用來(lái)布局UI使每月1號(hào)與星期隊(duì)形起來(lái)):</p>

-(NSInteger)getFirstDayWeekForMonth:(NSDate*)date
{
    // NSCalendarIdentifierGregorian : 指定日歷的算法
    NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    // NSDateComponents封裝了日期的組件,年月日時(shí)分秒等(個(gè)人感覺像是平時(shí)用的model模型)
    // 調(diào)用NSCalendar的components:fromDate:方法返回一個(gè)NSDateComponents對(duì)象
    // 需要的參數(shù)分別components:所需要的日期單位 date:目標(biāo)月份的date對(duì)象
    NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond|NSCalendarUnitWeekday fromDate:date];
    NSLog(@"NSDateComponents是這個(gè)樣子的:%@",comps);
    // 直接調(diào)用自己weekDay屬性
    NSInteger weekday = [comps weekday];
    #warning mark --找了很多原因不知道為什么星期數(shù)總是比實(shí)際快一天,有時(shí)間找更好的解決方法(暫時(shí)用-1天處理了)
    weekday--;
    NSLog(@"[comps weekday] = %ld",(long)weekday);
    if (weekday == 7) {
        return 0;
    }else return weekday;
}

<p>5. 當(dāng)前時(shí)間與之前時(shí)間的間隔:</p>

/**
 *  @author jaki, 15-09-21 17:09:42
 *  @brief  獲取一個(gè)標(biāo)準(zhǔn)時(shí)間戳與當(dāng)前時(shí)間的時(shí)間差
 *  @param tinterval 時(shí)間戳
 *  @return 距離當(dāng)前時(shí)間的時(shí)間間隔
 */
-(NSString *)getStandardTimeInterval:(NSTimeInterval)interval{
    //進(jìn)行時(shí)間差比較
    //當(dāng)前時(shí)間與1970時(shí)間戳(秒為單位)
    NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
    // 當(dāng)前時(shí)間戳-當(dāng)時(shí)時(shí)間戳=差值(比如朋友圈動(dòng)態(tài)發(fā)表時(shí)間為10分鐘前(當(dāng)前時(shí)間-發(fā)表時(shí)間))
    NSTimeInterval timeInterval = time-interval;
    //計(jì)算出天阵谚、小時(shí)、分鐘
    int day = timeInterval/(60*60*24);
    int hour = ((long)timeInterval%(60*60*24))/(60*60);
    int minite = ((long)timeInterval%(60*60*24))%(60*60)/60;
    NSMutableString * timeStr = [[NSMutableString alloc]init];
    // 邏輯判斷
    if (day!=0) {
        [timeStr appendString:[NSString stringWithFormat:@"%d天前",day]];
    }else{
        if (hour!=0) {
            [timeStr appendString:[NSString stringWithFormat:@"%d小時(shí)前",hour]];
        }else{
            if (minite<1) {
                [timeStr appendString:@"剛剛"];
            }else{
                [timeStr appendString:[NSString stringWithFormat:@"%d分鐘前",minite]];
            }
        }
    }
    return timeStr;
}

<p>6.獲取當(dāng)前系統(tǒng)時(shí)間:</p>

-(NSString *)getCurrentTime{
    NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
    <code>// 格式化系統(tǒng)時(shí)間字符串</code>
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString * time = [formatter stringFromDate:[NSDate date]];
    return time;
}

<p>7.返回年月日時(shí)分秒:</p>

<code>#pragma mark --- 對(duì)比上邊就比較簡(jiǎn)單了不過多啰嗦</code>
-(int)getYear{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];
    return (int)dateComponent.year;
    
}
-(int)getMonth{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags =  NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];
    return (int)dateComponent.month;
}
-(int)getDay{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags =  NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];
    return (int)dateComponent.day;
}
-(int)getHour{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags =  NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];
    return (int)dateComponent.hour;
}
-(int)getMinute{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags =  NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];
    return (int)dateComponent.minute;
}
-(int)getSecond{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags =  NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];
    return (int)dateComponent.second;
}

<p>8.date對(duì)象NSString互相轉(zhuǎn)換:</p>

// date對(duì)象轉(zhuǎn)換成字符串(最后return根據(jù)自己需求處理)
-(NSString * )theTargetDateConversionStr:(NSDate * )date
{
    NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];//實(shí)例化一個(gè)NSDateFormatter對(duì)象
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];//設(shè)定時(shí)間格式,這里可以設(shè)置成自己需要的格式
    NSString *currentDateStr = [dateFormat stringFromDate:date];
    // 根據(jù)自己需求處理字符串
    return [currentDateStr substringToIndex:7];
}
// NSString對(duì)象轉(zhuǎn)date
-(NSDate* )theTargetStringConversionDate:(NSString *)str
{
    //設(shè)置轉(zhuǎn)換格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *date=[formatter dateFromString:str];
    return date;
}
8個(gè)方法差不多能夠?qū)崿F(xiàn)一個(gè)簡(jiǎn)單點(diǎn)的日歷控件了烟具,88大發(fā),大功告成梢什。2017第一篇,比較偏基礎(chǔ)適合我這種菜鳥或者新手朝聋,大神路過的話就當(dāng)娛樂一下了嗡午。有錯(cuò)誤的話希望多多指點(diǎn)樓主一下

下面貼一下代碼以及實(shí)現(xiàn)思路:

思路:

剛知道要寫日歷的時(shí)候是懵逼的,對(duì)NSdate還好冀痕、NSCalendar完全沒有概念荔睹。查了挺多資料,也在github找了好幾個(gè)demo想直接拿過來(lái)用言蛇,不過不太合適所以決定自己寫僻他。試了tableView、跟colelctionView,最后選擇collectionView需求是展示當(dāng)前月跟之后三個(gè)月的日歷腊尚。

所以就:

區(qū)頭實(shí)現(xiàn)星期View->四個(gè)分區(qū)->區(qū)頭區(qū)尾配合實(shí)現(xiàn)效果吨拗,上邊聊得幾個(gè)方法處理DataSource.

日歷中標(biāo)記今天的思路是:

實(shí)例變量selectedIndex(今天的下標(biāo)): ---實(shí)現(xiàn)->(獲取到今天幾號(hào),加上今天周幾-1就是日歷中今天那個(gè)cell所在的位置了)

直接截圖代碼:

都比較基礎(chǔ)(自己保存下筆記婿斥,也分享給能用到的童鞋)

UICollectionView實(shí)現(xiàn):


collectionView.png

DataSource:每個(gè)分區(qū)返回item數(shù)量


dataSource返回item個(gè)數(shù).png

DataSource: 繪制item

dateSource繪制Cell.png

DataSource:headerView和footerView以及點(diǎn)擊回傳數(shù)據(jù):


區(qū)頭劝篷、區(qū)尾、點(diǎn)擊.png

demo地址:https://github.com/rundonkey/DzNSCalendar.git

到這我的這個(gè)懵逼寫日歷的過程就完畢了
Bug神在上請(qǐng)保佑所有正在奮斗的90后程序猿們2017永無(wú)bug民宿,保佑老猿們步步高升順順利利娇妓!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市活鹰,隨后出現(xiàn)的幾起案子哈恰,更是在濱河造成了極大的恐慌只估,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕊蝗,死亡現(xiàn)場(chǎng)離奇詭異仅乓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蓬戚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門夸楣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人子漩,你說我怎么就攤上這事豫喧。” “怎么了幢泼?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵紧显,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我缕棵,道長(zhǎng)孵班,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任招驴,我火速辦了婚禮篙程,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘别厘。我一直安慰自己虱饿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布触趴。 她就那樣靜靜地躺著氮发,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冗懦。 梳的紋絲不亂的頭發(fā)上爽冕,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音批狐,去河邊找鬼扇售。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嚣艇,可吹牛的內(nèi)容都是我干的承冰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼食零,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼困乒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起贰谣,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娜搂,失蹤者是張志新(化名)和其女友劉穎迁霎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體百宇,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡考廉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了携御。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昌粤。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖啄刹,靈堂內(nèi)的尸體忽然破棺而出涮坐,到底是詐尸還是另有隱情,我是刑警寧澤誓军,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布袱讹,位于F島的核電站,受9級(jí)特大地震影響昵时,放射性物質(zhì)發(fā)生泄漏捷雕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一壹甥、第九天 我趴在偏房一處隱蔽的房頂上張望非区。 院中可真熱鬧,春花似錦盹廷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至淆衷,卻和暖如春缸榄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祝拯。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工甚带, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佳头。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓鹰贵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親康嘉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子碉输,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容