[Swift通天遁地]一、超级工具,17自定义的CVCalendar日历

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

➤微信公众号:山青咏芝(shanqingyongzhi)

➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/

➤GitHub地址:https://github.com/strengthen/LeetCode

➤原文地址:

➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。

➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

目录:[Swift]通天遁地Swift

本文将演示另一款第三方的日历类库。

首先确保在项目中已经安装了所需的第三方库。

点击【Podfile】,查看安装配置文件。

1 platform :ios, '12.0'
2 use_frameworks!
3 
4 target 'DemoApp' do
5     source 'https://github.com/CocoaPods/Specs.git'
6     pod 'CVCalendar', '~> 1.4.0'
7 end

根据配置文件中的相关配置,安装第三方库。

然后点击打开【DemoApp.xcworkspace】项目文件。

在项目导航区,打开视图控制器的代码文件【ViewController.swift】

选择开始编写代码,创建一个日历控件。

  1 import UIKit
  2 //在当前类文件中,引入已经安装的第三方类库
  3 import CVCalendar
  4 
  5 class ViewController: UIViewController {
  6 
  7     //添加一个日历菜单视图变量,作为当前类的一个属性。
  8     //日历菜单将位于日历视图的上方,用来显示日历的星期。
  9     var menuView : CVCalendarMenuView!
 10     //添加一个日历视图变量,作为当前类的一个属性
 11     var calendarView : CVCalendarView!
 12     
 13     override func viewDidLoad() {
 14         super.viewDidLoad()
 15         // Do any additional setup after loading the view, typically from a nib.
 16         
 17         //设置当前根视图的背景颜色
 18         self.view.backgroundColor = UIColor(red: 239.0/255, green: 239.0/255, blue: 239.0/255, alpha: 1.0)
 19         
 20         //对日历菜单视图,进行初始化操作,并设置其显示区域位于屏幕上方。
 21         self.menuView = CVCalendarMenuView(frame: CGRect(x: 20, y: 40, width: 280, height: 15))
 22         
 23         //对日历视图进行初始化操作,并设置其显示区域
 24         self.calendarView = CVCalendarView(frame: CGRect(x: 20, y: 60, width: 280, height: 320))
 25         
 26         //设置日历视图的外观代理为当前的视图控制器对象
 27         self.calendarView.calendarAppearanceDelegate = self
 28         //设置日历视图的日历代理为当前的视图控制器对象
 29         self.calendarView.calendarDelegate = self
 30         //设置日历视图的动画代理为当前的视图控制器对象
 31         self.calendarView.animatorDelegate = self
 32 
 33         //设置日历菜单视图的菜单代理为当前视图控制器对象
 34         self.menuView.menuViewDelegate = self
 35         
 36         //依次将两个视图添加到根视图中
 37         self.view.addSubview(menuView)
 38         self.view.addSubview(calendarView)
 39     }
 40     
 41     //添加一个方法,用来监听视图控制器对它的子视图进行布局的事件
 42     override func viewDidLayoutSubviews()
 43     {
 44         //当监听到该事件时
 45         super.viewDidLayoutSubviews()
 46         
 47         //依次提交对菜单视图和日历视图的刷新
 48         self.menuView.commitMenuViewUpdate()
 49         self.calendarView.commitCalendarViewUpdate()
 50     }
 51     
 52     override func didReceiveMemoryWarning() {
 53         super.didReceiveMemoryWarning()
 54         // Dispose of any resources that can be recreated.
 55     }
 56 }
 57 
 58 //添加一个针对视图控制器的扩展,
 59 //并使其遵循日历视图协议和日历菜单视图协议。
 60 extension ViewController: CVCalendarViewDelegate, CVCalendarMenuViewDelegate
 61 {
 62     //添加一个代理方法,用来设置日历的模式
 63     func presentationMode() -> CalendarMode
 64     {
 65         //有月模式和周模式两种
 66         return .monthView
 67     }
 68     
 69     //添加一个代理方法
 70     func firstWeekday() -> Weekday {
 71         //将周日作为一个星期的开始
 72         return .sunday
 73     }
 74     
 75     //添加一个代理方法,设置在一个星期当中,每天的日期文字颜色
 76     func dayOfWeekTextColor(by weekday: Weekday) -> UIColor
 77     {
 78         //当该日为周日时,设置文字颜色为红色,否则设置文字颜色为黑色
 79         return weekday == .sunday ? UIColor.red : UIColor.black
 80     }
 81     
 82     //添加一个代理方法,用来设置允许突出显示某个日期
 83     func shouldShowWeekdaysOut() -> Bool
 84     {
 85         return true
 86     }
 87     
 88     //添加一个代理方法,用来允许以动态的方式进行尺寸的缩放
 89     func shouldAnimateResizing() -> Bool
 90     {
 91         return true
 92     }
 93     
 94     //添加一个代理方法,用来设置是否选中某个日期视图
 95     private func shouldSelectDayView(dayView: DayView) -> Bool
 96     {
 97         //此处使用随机的方式来决定是否选中
 98         return arc4random_uniform(3) == 0 ? true : false
 99     }
100     
101     //添加一个代理方法,用来响应某个日期被选中的事件,
102     func didSelectDayView(_ dayView: CVCalendarDayView, animationDidFinish: Bool)
103     {
104         //在控制台输出选中的日期
105         print("\(dayView.date.commonDescription) is selected!")
106     }
107     
108     //添加一个代理方法,用来设置是否允许在日期的上方,显示一个标识符
109     func topMarker(shouldDisplayOnDayView dayView: CVCalendarDayView) -> Bool
110     {
111         return true
112     }
113     
114     //添加一个代理方法,用来设置是否允许在日期的上方,显示一个点标识
115     func dotMarker(shouldShowOnDayView dayView: CVCalendarDayView) -> Bool
116     {
117         //获得当前位置上的日期的天数
118         let day = dayView.date.day
119         //通过随机函数生成一个0到30之间的数字
120         let randomDay = Int(arc4random_uniform(31))
121         //假如当前位置上的日期的天数,和随机数字相同时,
122         //则在日期的位置显示一个点标识
123         if day == randomDay
124         {
125             return true
126         }
127         
128         //其他的情况则不现实点标识
129         return false
130     }
131     
132     //添加一个代理方法,用来设置点标识的颜色
133     func dotMarker(colorOnDayView dayView: CVCalendarDayView) -> [UIColor]
134     {
135         //通过随机函数生成一个随机的颜色
136         let red = CGFloat(arc4random_uniform(600) / 255)
137         let green = CGFloat(arc4random_uniform(600) / 255)
138         let blue = CGFloat(arc4random_uniform(600) / 255)
139         
140         //初始化一个随机的颜色常量
141         let color = UIColor(red: red, green: green, blue: blue, alpha: 1)
142         
143         //生成一个在1和3之间的随机整数
144         let numberOfDots = Int(arc4random_uniform(3) + 1)
145         //根据随机整数进行判断
146         //根据随机整数的值,返回不同长度的颜色数组
147         switch(numberOfDots)
148         {
149             case 2:
150                 return [color, color]
151             case 3:
152                 return [color, color, color]
153             default:
154                 return [color]
155         }
156     }
157     
158     //添加一个代理方法,设置是否在日期上显示高亮效果
159     func dotMarker(shouldMoveOnHighlightingOnDayView dayView: CVCalendarDayView) -> Bool
160     {
161         return true
162     }
163     
164     //添加一个代理方法,设置点标识的尺寸
165     func dotMarker(sizeOnDayView dayView: DayView) -> CGFloat
166     {
167         return 13
168     }
169     
170     //添加一个代理方法,设置星期的显示方式
171     func weekdaySymbolType() -> WeekdaySymbolType
172     {
173         //有正常、缩写和超级缩写三种样式可以选择
174         return .short
175     }
176     
177     //添加一个代理方法,用来设置选区视图的贝塞尔路径
178     func selectionViewPath() -> ((CGRect) -> (UIBezierPath))
179     {
180         //返回日期视图的显示区域,作为选区视图的路径
181         return { UIBezierPath(rect: CGRect(x: 0, y: 0, width: $0.width, height: $0.height)) }
182     }
183     
184     //添加一个代理方法,不允许显示自定义的单独选区
185     func shouldShowCustomSingleSelection() -> Bool
186     {
187         return false
188     }
189     
190     //添加一个代理方法,用来设置显示在日期上的辅助视图
191     func preliminaryView(viewOnDayView dayView: DayView) -> UIView
192     {
193         //初始化一个辅助视图,设置其显示区域和日期视图相同,并且形状为圆形。
194         let circleView = CVAuxiliaryView(dayView: dayView, 
195                                          rect: dayView.frame, 
196                                          shape: CVShape.circle)
197         //设置辅助视图的填充颜色为浅灰色
198         circleView.fillColor = .colorFromCode(0xCCCCCC)
199         //返回该辅助视图
200         return circleView
201     }
202     
203     //添加一个代理方法,用来设置是否允许在日期视图上,显示一个辅助视图
204     func preliminaryView(shouldDisplayOnDayView dayView: DayView) -> Bool
205     {
206         //设置当日期视图中的日期为当日的天数时,显示辅助视图,否则不显示
207         if (dayView.isCurrentDay)
208         {
209             return true
210         }
211         //否则不显示
212         return false
213     }
214     
215     //添加一个代理方法,用来设置补充视图。
216     //该补充视图将被用来在所有属于星期五的天数位置,绘制一个圆环。
217     func supplementaryView(viewOnDayView dayView: DayView) -> UIView
218     {
219         //初始化一个圆周率常数
220         let π = M_PI
221         
222         //初始化一个浮点类型的常量,作为圆环的间距
223         let ringSpacing: CGFloat = 3.0
224         //初始化另一个浮点类型的常量,作为圆环的宽度
225         let ringInsetWidth: CGFloat = 1.0
226         //初始化另一个浮点类型的常量,作为圆环在垂直方向上的偏移距离
227         let ringVerticalOffset: CGFloat = 1.0
228         //创建一个图形层变量,用来绘制圆环
229         var ringLayer: CAShapeLayer!
230         //设置圆环路径的宽度为1
231         let ringLineWidth: CGFloat = 1.0
232         //设置圆环的线条颜色为紫色
233         let ringLineColour: UIColor = UIColor.purple
234         
235         //在此创建一个和日期视图相比,
236         //具有相同显示区域的视图对象。
237         let newView = UIView(frame: dayView.bounds)
238         
239         //通过计算获得圆环的直径数据
240         let diameter: CGFloat = (newView.bounds.width) - ringSpacing
241         //通过直径算出半径的大小
242         let radius: CGFloat = diameter / 2.0
243         
244         //从而创建一个矩形区域,用来绘制圆环形状
245         let rect = CGRect(x: newView.frame.midX-radius, y: newView.frame.midY-radius-ringVerticalOffset, width: diameter, height: diameter)
246         
247         //对图形层进行初始化操作,
248         ringLayer = CAShapeLayer()
249         //并将该层添加到新建视图的层中。
250         newView.layer.addSublayer(ringLayer)
251         
252         //设置层的填充颜色为无色
253         ringLayer.fillColor = nil
254         //设置层的线条宽度
255         ringLayer.lineWidth = ringLineWidth
256         //设置层的描边属性
257         ringLayer.strokeColor = ringLineColour.cgColor
258         
259         //初始化一个浮点常量,作为圆环的线宽嵌入值。
260         let ringLineWidthInset: CGFloat = CGFloat(ringLineWidth/2.0) + ringInsetWidth
261         //通过调用矩形区域对象的相关方法,获得该矩形区域具有相同中心点,但是更大的另一个矩形区域
262         let ringRect: CGRect = rect.insetBy(dx: ringLineWidthInset, dy: ringLineWidthInset)
263         //获得该区域的中心点坐标
264         let centrePoint: CGPoint = CGPoint(x: ringRect.midX, y: ringRect.midY)
265         //获得绘制圆环的起点角度
266         let startAngle: CGFloat = CGFloat(-π/2.0)
267         //生成绘制圆环的结束点角度
268         let endAngle: CGFloat = CGFloat(π * 2.0) + startAngle
269         //通过中心点、半径、起点角度、结束点角度以及是否顺时针等数据,
270         //创建一个环形路径
271         let ringPath: UIBezierPath = UIBezierPath(arcCenter: centrePoint, //中心点
272                                                   radius: ringRect.width/2.0, //半径
273                                                   startAngle: startAngle, //起点角度
274                                                   endAngle: endAngle, //结束点角度
275                                                   clockwise: true)//是否顺时针
276         //设置层的路径为环形路径
277         ringLayer.path = ringPath.cgPath
278         //设置层的显示区域,和当前的日期层保持相同
279         ringLayer.frame = newView.layer.bounds
280         
281         //最后返回设置好的附加视图
282         return newView
283     }
284     
285     //添加一个代理方法,用来设置在何种情况下,允许显示辅助视图。
286     func supplementaryView(shouldDisplayOnDayView dayView: DayView) -> Bool
287     {
288         //当某处的日期的天数为周五时,在该日期位置显示一个辅助视图,
289         //否则不会显示辅助视图。
290         if (dayView.date.weekDay == Weekday.friday)
291         {
292             return true
293         }
294         
295         return false
296     }
297     
298     //设置星期文本的颜色为黑色
299     func dayOfWeekTextColor() -> UIColor
300     {
301         return UIColor.black
302     }
303     
304     //添加一个代理方法,设置星期文本的背景颜色为无色
305     func dayOfWeekBackGroundColor() -> UIColor
306     {
307         return UIColor.clear
308     }
309 }