[Swift通天遁地]一、超级工具-(17)自定义的CVCalendar日历
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10176124.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
本文将演示另一款第三方的日历类库。
首先确保在项目中已经安装了所需的第三方库。
点击【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 }