iOS 自定义日历的实现

Swift 3.0版本的日历~~

1.首先,自定义日历的载体一定是CollectionView了~

2.然后,最关键的就是获取日历的信息了:当前日期,月份,1号是星期几,当前月份有多少天了... 通过这些信息,就可以确定每一个cell应该显示什么信息了.

    //MARK: - Private

    

    internal func dateInfo(date: Date) -> (DateComponents) {

        let components = Calendar.current.dateComponents([Calendar.Component.year, Calendar.Component.month, Calendar.Component.day], from: date)

        return components

    }

    

    internal func firstWeekDayThisMonth(date: Date) -> (Int) {

        var components = Calendar.current.dateComponents([Calendar.Component.year, Calendar.Component.month, Calendar.Component.day], from: date)

        components.day = 1

        let firstDayOfMonthDate = Calendar.current.date(from: components)

        let firstWeekDay = Calendar.current.ordinality(of: Calendar.Component.weekday, in: Calendar.Component.weekOfMonth, for: firstDayOfMonthDate!)

        return firstWeekDay!

    }

    

    internal func totalDaysThisMonth(date: Date) -> (Int) {

        let totalDaysThisMonth:Range = Calendar.current.range(of: Calendar.Component.day, in: Calendar.Component.month, for: date)!

        return totalDaysThisMonth.count

    }


3. 结构层次间下图~绿色的cell是负责显示日期的cell,黄色的cell是显示星期几的cell.


4.实现数据源方法. 如果需要实现其他功能,可以通过设置代理来实现.

extension CalendarViewController: UICollectionViewDataSource {


    func numberOfSections(in collectionView: UICollectionView) -> Int {

        return 2

    }

    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        return section == 0 ? 7 : 37

    }

    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        

        let currentDateComponents = dateInfo(date: Date())

        var selectedComponents = dateInfo(date: date)

        selectedComponents.day = indexPath.item - firstWeekDayThisMonth(date: date) + 2

        

        if indexPath.section == 0 {

            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DayOfAWeekCell", for: indexPath) as! CalendarDateCell

            cell.dateLabel.text = dateArray[indexPath.item]

            return cell

        } else {

            let cell = collectionView .dequeueReusableCell(withReuseIdentifier:"CalendarCell", for: indexPath) as! CalendarDateCell

            if indexPath.item < firstWeekDayThisMonth(date: date) - 1 {

                cell.dateLabel.text = " "

                cell.backgroundColor = UIColor.clear

            }else if indexPath.item >= firstWeekDayThisMonth(date: date) - 1 && (indexPath.item - firstWeekDayThisMonth(date: date) + 2) <= totalDaysThisMonth(date: date) {

                cell.dateLabel.text = "\(indexPath.item - firstWeekDayThisMonth(date: date) + 2)"

                if currentDateComponents == selectedComponents {

                    cell.backgroundColor = UIColor.orange

                }else{

                    cell.backgroundColor = UIColor.green

                }

            }else {

                cell.backgroundColor = UIColor.clear

                cell.dateLabel.text = " "

            }

            return cell

        }

    }

}


extension CalendarViewController: UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        if indexPath.item >= firstWeekDayThisMonth(date: date) - 1 && (indexPath.item - firstWeekDayThisMonth(date: date) + 2) <= totalDaysThisMonth(date: date) {

            var selectedComponents = dateInfo(date: date)

            selectedComponents.day = indexPath.item - firstWeekDayThisMonth(date: date) + 2

            self.selectedComponents = selectedComponents

            self.selectedIndexPath = indexPath

        }

    }

}


设置好这些,大体的日历就可以实现了~

大体的思路就是这样,由于时间原因没有写的特别详细,有问题的小伙伴可以评论留言,我们可以一起讨论讨论.

或者直接去看源码~ 有什么意见欢迎大家指点~~ 

源码地址:https://github.com/LoKiLyn/Calendar





你可能感兴趣的:(iOS 自定义日历的实现)