日历的实现|日历的实现 in Swift

首先,这个demo,我真的,纯手写了两遍,第一次刚写完往github上迁移的时候手欠点了replace,导致所有代码没有了,真的就没有了。如果有大神知道如果发生这样的事如何补救请及时告诉我,防止我下次犯蠢的时候能不用敲第二遍。
日历的实现|日历的实现 in Swift
文章图片
性冷淡风 1.控件:
习惯于把控件用懒加载的形式创建出来,把可以定性的属性先写出来,之后有什么改动直接过来改就行,代码会工整很多。
【日历的实现|日历的实现 in Swift】// 时间Label

lazy var timeLabel: UILabel = { let time = UILabel(frame: CGRectZero) time.text = "xxxx-xx" time.textAlignment = .Center self.view.addSubview(time) return time }()

// collectionView
var myCollection: UICollectionView!

// 上个月
lazy var lastButton: UIButton = { let last = UIButton(type: .System) last.setTitle("<--", forState: .Normal) last.setTitleColor(UIColor.blackColor(), forState: .Normal) last.addTarget(self, action: #selector(lastAction), forControlEvents: .TouchUpInside) self.view.addSubview(last) return last }()

// 下个月
lazy var nextButton: UIButton = { let next = UIButton(type: .System) next.setTitle("-->", forState: .Normal) next.setTitleColor(UIColor.blackColor(), forState: .Normal) next.addTarget(self, action: #selector(nextAction), forControlEvents: .TouchUpInside) self.view.addSubview(next) return next }()

2.布局:
UICollectionView
基本布局就是这样的,collectionView用的很少,把这些属性写明白了基本上可以显示出来了。
let item = KScreenWidth / 7 - 5 let layout = UICollectionViewFlowLayout() layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0) layout.itemSize = CGSizeMake(item, item) layout.minimumLineSpacing = 2 layout.minimumInteritemSpacing = 2 let rect = CGRectMake(10, lastButton.frame.maxY, KScreenWidth, 400) myCollection = UICollectionView(frame: rect, collectionViewLayout: layout) myCollection.backgroundColor = UIColor.whiteColor() myCollection.dataSource = self myCollection.delegate = self self.view.addSubview(myCollection)

3.最关键的,获取关于日历的基本信息:
// 获取当前日期
func day(date: NSDate) -> NSInteger { let com = NSCalendar.currentCalendar().components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: date) return com.day }

// 获取当前月
func month(date: NSDate) -> NSInteger { let com = NSCalendar.currentCalendar().components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: date) return com.month }

// 获取当前年
func year(date: NSDate) -> NSInteger { let com = NSCalendar.currentCalendar().components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: date) return com.year }

// 每个月1号对应的星期
func firstWeekInThisMonth(date: NSDate) -> NSInteger { let calender = NSCalendar.currentCalendar() calender.firstWeekday = 1 let com = calender.components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: date) com.day = 1 let firstDay = calender.dateFromComponents(com) let firstWeek = calender.ordinalityOfUnit(NSCalendarUnit.Weekday, inUnit: NSCalendarUnit.WeekOfMonth, forDate: firstDay!) return firstWeek - 1 }

// 当前月份的天数
func daysInThisMonth(date: NSDate) -> NSInteger { let days = NSCalendar.currentCalendar().rangeOfUnit(NSCalendarUnit.Day, inUnit: NSCalendarUnit.Month, forDate: date) return days.length }

// 上个月
func lastMonth(date: NSDate) -> NSDate { let dateCom = NSDateComponents() dateCom.month = -1 let newDate = NSCalendar.currentCalendar().dateByAddingComponents(dateCom, toDate: date, options: NSCalendarOptions.MatchStrictly) return newDate! }

// 下个月
func nextMonth(date: NSDate) -> NSDate { let dateCom = NSDateComponents() dateCom.month = +1 let newDate = NSCalendar.currentCalendar().dateByAddingComponents(dateCom, toDate: date, options: NSCalendarOptions.MatchStrictly) return newDate! }

4.关于上个月、下个月按钮的响应事件:
// 上个月按钮响应事件
func lastAction() {UIView.transitionWithView(self.myCollection, duration: 0.5, options: .TransitionCurlDown, animations: { self.date = self.lastMonth(self.date) self.timeLabel.text = String(format: "%li-%.2ld", self.year(self.date), self.month(self.date)) }, completion: nil) self.myCollection.reloadData() }

// 下个月按钮响应事件
func nextAction() { UIView.transitionWithView(self.myCollection, duration: 0.5, options: .TransitionCurlUp, animations: { self.date = self.nextMonth(self.date) self.timeLabel.text = String(format: "%li-%.2ld", self.year(self.date), self.month(self.date)) }, completion: nil)self.myCollection.reloadData() }

5. 日历的显示
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { switch indexPath.section { case 0: let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! WeekCollectionViewCell cell.timeLabel.text = dateArray[indexPath.row] as? String return celldefault: let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CELL", forIndexPath: indexPath) as! DateCollectionViewCell let days = self.daysInThisMonth(date) let week = self.firstWeekInThisMonth(date) var day = 0 let index = indexPath.row if index < week { cell.timeLabel.text = " " } else if index > week + days - 1 { cell.backgroundColor = UIColor.redColor() } else { day = index - week + 1 cell.timeLabel.text = String(day) } return cell } }

设置两个分区:① 星期 ② 日历
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return 2 }

根据不同的section放置不同数量的cell
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return dateArray.count default: let days = self.daysInThisMonth(date) let firstWeek = self.firstWeekInThisMonth(date) let day = days + firstWeek return day } }

6.日历标识当前日期:
(这里写的比较纠结,充分体现了我内心复杂的系统,求大神给出更简单的方法。)
let da = NSDate() let com = NSCalendar.currentCalendar().components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: da) let abc = String(format: "%li-%.2ld", com.year, com.month) if self.timeLabel.text! == abc { if cell.timeLabel.text == String(self.day(date)) { cell.backgroundColor = UIColor.grayColor() } else { cell.backgroundColor = UIColor.whiteColor() } } else { cell.backgroundColor = UIColor.whiteColor() }

swift力大无穷,大家一起进步吧~~~
最后最重要的:
GitHub地址: https://github.com/SummerOO/CalenderDemo
有什么可以改进的希望大神可以指出~

    推荐阅读