日历的实现 in Swift

首先,这个demo,我真的,纯手写了两遍,第一次刚写完往github上迁移的时候手欠点了replace,导致所有代码没有了,真的就没有了。如果有大神知道如果发生这样的事如何补救请及时告诉我,防止我下次犯蠢的时候能不用敲第二遍。

性冷淡风

1.控件:

习惯于把控件用懒加载的形式创建出来,把可以定性的属性先写出来,之后有什么改动直接过来改就行,代码会工整很多。

// 时间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 cell
        
    default:
        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
有什么可以改进的希望大神可以指出~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容