1. 程式人生 > >[Swift通天遁地]一、超級工具-(17)自定義的CVCalendar日曆

[Swift通天遁地]一、超級工具-(17)自定義的CVCalendar日曆

本文將演示另一款第三方的日曆類庫。

首先確保在專案中已經安裝了所需的第三方庫。

點選【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 }