日历的实现 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
有什么可以改进的希望大神可以指出~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容