太長時間沒有寫文章了译柏,最近幾個月一直忙找工作的事情,現(xiàn)在終于塵埃落定奈搜,于是又從OC的坑掉進了swift的坑里悉盆,不過大家不要擔心,樓主是不會丟棄掉OC的媚污,這篇文章也是針對OC于swift區(qū)別來寫的,說出來一把辛酸淚舀瓢。不說了,直接進入正題吧耗美。
這次的文章不做日歷的詳細介紹京髓,因為是其本身已經封裝好的,這次只是針對swift日歷的具體用法做一個介紹商架,直接上代碼堰怨。
首先先看一下效果圖:
可以自動翻頁,萬年歷蛇摸,可以選中日期回傳
這里寫的日歷主要用了NSCalendar這個API备图,對應的swift用的Calendar,這里的話先介紹一下官方API是怎么解釋NSCalendar的:
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對象封裝了關于一年的開始赶袄,長度和分割定義的推算時間的信息揽涮。 它們提供有關日歷的信息,并支持日歷計算饿肺,例如確定給定的日歷單位的范圍蒋困,并將單位添加到給定的絕對時間
多的不需要太多的介紹,直接看用法吧:
首先是計算當前日期或選擇的日期是幾號:
//OC版本
-(NSInteger)dayWithDate:(NSDate *)date{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *component = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
return component.day;
}
//swift版本
func day(date : Date) -> NSInteger {
let calendar = Calendar.current
let componentsSet = Set<Calendar.Component>([.year, .month, .day,])
var componentss = calendar.dateComponents(componentsSet, from: date)
return componentss.day!
}
這里要注意的是敬辣,swift不能像OC直接使用NSCalendarUnit單位并且用單目運算符連接雪标,而是需要用Set對象承載起來使用Set對象,同理這里返回的是日子溉跃,而返回月和年只需要改為month和year即可村刨。
計算每個月1號對應周幾
//OC版本
- (NSInteger)firstWeekDayInThisMonthWithDate:(NSDate *)date{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *component = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
calendar.firstWeekday = 1;
component.day = 1;
NSDate *firstDate = [calendar dateFromComponents:component];
return [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDate] - 1;
}
//swift版本
func firstWeekDayInThisMonth(date : Date) -> NSInteger {
var calendar = Calendar.current
let componentsSet = Set<Calendar.Component>([.year, .month, .day,])
var componentss = calendar.dateComponents(componentsSet, from: date)
calendar.firstWeekday = 1
componentss.day = 1
let first = calendar.date(from: componentss)
let firstWeekDay = calendar.ordinality(of: .weekday, in: .weekOfMonth, for: first!)
return firstWeekDay! - 1
}
計算當前月份天數(shù)
//OC版本
- (NSInteger)totalDaysInThisMonthWithDate:(NSDate *)date{
return [[NSCalendar currentCalendar]rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
}
//swift版本
func totalDaysInThisMonth(date : Date) -> NSInteger {
let totalDays : Range = Calendar.current.range(of: .day, in: .month, for: date)!
return totalDays.count
}
計算指定月天數(shù)
//OC版本
- (NSInteger)getDaysInMonthWithYearAndMonth:(NSInteger)year month:(NSInteger)month{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy-MM";
//這里視具體情況而定,如果日期帶有前綴0的可不要,我這里是傳入了單數(shù)字日期
NSString *monthStr = @"";
if (month < 10) {
monthStr = [NSString stringWithFormat:@"0%ld",month];
}else{
monthStr = [NSString stringWithFormat:@"%ld",month];
}
NSString *dateStr = [NSString stringWithFormat:@"%ld-%@",year,monthStr];
NSDate *date = [dateFormatter dateFromString:dateStr];
//NSCalendarIdentifierGregorian公歷日歷的意思
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
return [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
}
//swift版本
func getDaysInMonth( year: Int, month: Int) -> Int{
let dateFor = DateFormatter.init()
dateFor.dateFormat = "yyyy-MM"
var monthStr = ""
if month < 10 {
monthStr = "0" + String(month)
}else{
monthStr = String(month)
}
let dateStr = String(year) + "-" + monthStr
let date = dateFor.date(from: dateStr)
let calenDar = Calendar.init(identifier: Calendar.Identifier.gregorian)
let totaldays : Range = calenDar.range(of: .day, in: .month, for: date!)!
return totaldays.count
}
//這里的這個id字段NSCalendarIdentifierGregorian是公歷的意思撰茎,其余的可以通過官方文檔查閱
上一個月
//OC版本
- (NSDate *)nextMonthWithDate:(NSDate *)date{
NSDateComponents *component = [[NSDateComponents alloc] init];
component.month = -1;
return [[NSCalendar currentCalendar]dateByAddingComponents:component toDate:date options:NSCalendarMatchStrictly];
}
//swift版本
func lastMonth(date : Date) -> Date {
var dateComponents = DateComponents.init()
dateComponents.month = -1
let newDate = Calendar.current.date(byAdding: dateComponents, to: date)
return newDate!
}
這里說一下OC的那個options的屬性嵌牺,swift沒有用到。這里OC使用的是NSCalendarMatchStrictly這么個東西,開始查閱別人用的日歷用到這個玩意兒的時候一臉懵逼不知道是什么東西髓梅,后來專門查閱了下這個屬性也沒有人做解釋拟蜻,于是只好自己去官方文檔上查閱,在查閱完成后原諒我自己英語不太好枯饿,翻譯為中文之后也大概沒有懂什么意思酝锅,只是知其一二,現(xiàn)在給大家貼上,英文就是官方API原文奢方,中文當然就是是翻譯過來的意思了搔扁,具體應用可以視自己情況而定:
NSCalendarWrapComponents
Specifies that the components specified for an NSDateComponents object should be incremented and wrap around to zero/one on overflow, but should not cause higher units to be incremented.
指定為NSDateComponents對象指定的組件應該遞增,并在溢出時循環(huán)為零/ 1蟋字,但不應導致更高的單位增加稿蹲。
NSCalendarMatchStrictly
Specifies that the operation should travel as far forward or backward as necessary looking for a match.
指定操作應該根據(jù)需要前進或后退,尋找匹配鹊奖。
NSCalendarSearchBackwards
Specifies that the operation should travel backwards to find the previous match before the given date.
指定操作向后移動以在給定日期之前找到先前的匹配苛聘。
NSCalendarMatchPreviousTimePreservingSmallerUnits
Specifies that, when there is no matching time before the end of the next instance of the next highest unit specified in the given NSDateComponents object, this method uses the previous existing value of the missing unit and preserves the lower units' values.
指定當在給定的NSDateComponents對象中指定的下一個最高單位的下一個實例的結束之前沒有匹配的時間時,此方法使用缺失單元的先前存在的值忠聚,并保留較低單位的值设哗。
NSCalendarMatchNextTimePreservingSmallerUnits
Specifies that, when there is no matching time before the end of the next instance of the next highest unit specified in the given NSDateComponents object, this method uses the next existing value of the missing unit and preserves the lower units' values.
指定當在給定的NSDateComponents對象中指定的下一個最高單位的下一個實例的結束之前沒有匹配的時間時,此方法使用缺少單元的下一個現(xiàn)有值并保留較低單位的值两蟀。
NSCalendarMatchNextTime
Specifies that, when there is no matching time before the end of the next instance of the next highest unit specified in the given NSDateComponents object, this method uses the next existing value of the missing unit and does not preserve the lower units' values.
指定當在給定的NSDateComponents對象中指定的下一個最高單位的下一個實例的結束之前沒有匹配的時間時网梢,此方法使用缺少單元的下一個現(xiàn)有值,并且不保留較低單位的值赂毯。
NSCalendarMatchFirst
Specifies that, if there are two or more matching times, the operation should return the first occurrence.
指定如果有兩個或更多匹配的時間战虏,操作應該返回第一個出現(xiàn)的。
NSCalendarMatchLast
Specifies that, if there are two or more matching times, the operation should return the last occurrence.
指定如果有兩個或更多匹配的時間党涕,則操作應返回最后一次出現(xiàn)的烦感。
好了,基本代碼介紹完畢膛堤,日歷主體是使用collectionView實現(xiàn)的啸盏,中間如果有不好的地方或者大家有改進的地方歡迎評論去留言討論。
下面給上代碼地址:
OC版本:https://github.com/Archerry/Calendar_OC
swift版本:https://github.com/Archerry/Calendar_swift