QDatePicker.swift 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. //
  2. // QDatePicker.swift
  3. // O2Platform
  4. // 来自GitHub上的https://github.com/qyfeng009/QTimePicker
  5. //
  6. // Created by FancyLou on 2019/5/7.
  7. // Copyright © 2019 zoneland. All rights reserved.
  8. //
  9. import UIKit
  10. private let screenWidth = UIScreen.main.bounds.width
  11. private let screenHeight = UIScreen.main.bounds.height
  12. private let keyWindow = UIApplication.shared.keyWindow
  13. private let yearLH: CGFloat = 226.0
  14. private let sureVH: CGFloat = 44.0
  15. private let margin: CGFloat = 10.0
  16. class QDatePicker: UIView, UIGestureRecognizerDelegate, UIPickerViewDelegate, UIPickerViewDataSource {
  17. enum QPickerStyle {
  18. case datePicker // 时间选择器
  19. case singlePicker // 单项选择器
  20. }
  21. enum DatePickerStyle { // 此只在 datePicker 下生效
  22. case YMDHM // 选择 年月日时分
  23. case YMD // 选择 年月日
  24. case MDHM // 选择 月日时分
  25. case MD // 选择 月日
  26. case HM // 选择 时分
  27. }
  28. enum AminationStyle {
  29. case styleDefault // 默认弹出样式
  30. case styleOptional // 可选弹出样式
  31. }
  32. typealias DidSelectedDate = (_ date: String) -> Void ///< 定义确认回调
  33. private var selectedBack: DidSelectedDate?
  34. var sureView: UIButton!
  35. var yearL: UILabel!
  36. open var pickerStyle: QPickerStyle = .datePicker ///< 选择样式 默认 datePicker
  37. open var datePickerStyle: DatePickerStyle = .MDHM ///< 日期选择样式 默认 MDHM,只在 datePicker 样式下
  38. open var animationStyle: AminationStyle = .styleDefault { ///< 弹出动画样式 默认 styleDefault
  39. didSet {
  40. if animationStyle == .styleOptional {
  41. yearL.y = -yearLH
  42. yearL.transform = CGAffineTransform.identity
  43. sureView.y = screenHeight
  44. sureView.transform = CGAffineTransform.identity
  45. }
  46. }
  47. }
  48. open var themeColor: UIColor? = UIColor.hexInt(0x00B3C4) { ///< 主题颜色样式
  49. didSet {
  50. sureView.backgroundColor = themeColor
  51. }
  52. }
  53. open var singlePickerDatas: [String] = [] {
  54. didSet {
  55. singleSelectedData = singlePickerDatas[0]
  56. }
  57. } // 单项选择器数据源
  58. private var singleSelectedData: String = ""
  59. private lazy var pickerView: UIPickerView = {
  60. let pickerView = UIPickerView(frame: CGRect(x: 0, y: 0, width: yearL.width, height: yearL.height))
  61. pickerView.backgroundColor = .clear
  62. pickerView.showsSelectionIndicator = true
  63. pickerView.delegate = self
  64. pickerView.dataSource = self
  65. return pickerView
  66. }()
  67. init(selectedDate: @escaping DidSelectedDate) {
  68. super.init(frame: UIScreen.main.bounds)
  69. selectedBack = selectedDate
  70. let tapGesture = UITapGestureRecognizer(target: self, action: #selector(close))
  71. tapGesture.delegate = self
  72. addGestureRecognizer(tapGesture)
  73. backgroundColor = .clear
  74. yearL = UILabel(frame: CGRect(x: margin, y: screenHeight, width: screenWidth - margin * 2, height: yearLH))
  75. yearL.transform = CGAffineTransform.identity
  76. yearL.isUserInteractionEnabled = true
  77. yearL.backgroundColor = .white
  78. yearL.textColor = UIColor.hexInt(0xE9ECF2)
  79. yearL.textAlignment = NSTextAlignment.center
  80. yearL.font = UIFont.systemFont(ofSize: 110)
  81. yearL.adjustsFontSizeToFitWidth = true
  82. addSubview(yearL)
  83. yearL.roundedCorners(cornerRadius: 10, rectCorner: UIRectCorner([.topLeft, .topRight]))
  84. sureView = UIButton(type: UIButton.ButtonType.system)
  85. sureView.frame = CGRect(x: margin, y: yearL.y + yearL.height, width: yearL.width, height: sureVH)
  86. sureView.transform = CGAffineTransform.identity
  87. sureView.setTitle("确认", for: UIControl.State.normal)
  88. sureView.setTitleColor(.white, for: UIControl.State.normal)
  89. sureView.backgroundColor = themeColor
  90. sureView.addTarget(self, action: #selector(sureDate(_:)), for: UIControl.Event.touchUpInside)
  91. addSubview(sureView)
  92. sureView.roundedCorners(cornerRadius: 10, rectCorner: UIRectCorner([.bottomLeft, .bottomRight]))
  93. if pickerStyle == .datePicker {
  94. self.initDefaultDate()
  95. }
  96. }
  97. required init?(coder aDecoder: NSCoder) {
  98. fatalError("init(coder:) has not been implemented")
  99. }
  100. /// 弹出 Picker datePicker类型 可以定义默认显示的时间
  101. open func showDatePicker(defaultDate: Date = Date()) {
  102. if self.pickerStyle != .datePicker {
  103. self.show()
  104. return
  105. }
  106. keyWindow?.addSubview(self)
  107. keyWindow?.bringSubviewToFront(self)
  108. if animationStyle == .styleDefault {
  109. var duraton = 0.8
  110. var y = -(margin + yearLH + sureVH)
  111. if screenHeight == 812 {
  112. y -= 34
  113. duraton = 1.0
  114. }
  115. UIView.animate(withDuration: duraton, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  116. self.backgroundColor = UIColor.black.withAlphaComponent(0.4)
  117. self.sureView.transform = CGAffineTransform(translationX: 0, y: y)
  118. })
  119. UIView.animate(withDuration: duraton, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  120. self.yearL.transform = CGAffineTransform(translationX: 0, y: y)
  121. }, completion: { (finish: Bool) in
  122. self.yearL.addSubview(self.pickerView)
  123. self.resetDateShow(date: defaultDate)
  124. })
  125. } else {
  126. UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  127. self.backgroundColor = UIColor.black.withAlphaComponent(0.4)
  128. self.sureView.transform = CGAffineTransform(translationX: 0, y: -sureVH-(screenHeight/2 - (yearLH + sureVH)/2))
  129. })
  130. UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  131. self.yearL.transform = CGAffineTransform(translationX: 0, y: (yearLH + screenHeight/2-(yearLH + sureVH)/2))
  132. }, completion: { (finish: Bool) in
  133. self.yearL.addSubview(self.pickerView)
  134. self.resetDateShow(date: defaultDate)
  135. })
  136. }
  137. }
  138. /// 弹出 Picker
  139. open func show() {
  140. keyWindow?.addSubview(self)
  141. keyWindow?.bringSubviewToFront(self)
  142. if animationStyle == .styleDefault {
  143. var duraton = 0.8
  144. var y = -(margin + yearLH + sureVH)
  145. if screenHeight == 812 {
  146. y -= 34
  147. duraton = 1.0
  148. }
  149. UIView.animate(withDuration: duraton, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  150. self.backgroundColor = UIColor.black.withAlphaComponent(0.4)
  151. self.sureView.transform = CGAffineTransform(translationX: 0, y: y)
  152. })
  153. UIView.animate(withDuration: duraton, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  154. self.yearL.transform = CGAffineTransform(translationX: 0, y: y)
  155. }, completion: { (finish: Bool) in
  156. self.yearL.addSubview(self.pickerView)
  157. if self.pickerStyle == .datePicker {
  158. self.resetDateShow(date: Date())
  159. }
  160. })
  161. } else {
  162. UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  163. self.backgroundColor = UIColor.black.withAlphaComponent(0.4)
  164. self.sureView.transform = CGAffineTransform(translationX: 0, y: -sureVH-(screenHeight/2 - (yearLH + sureVH)/2))
  165. })
  166. UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  167. self.yearL.transform = CGAffineTransform(translationX: 0, y: (yearLH + screenHeight/2-(yearLH + sureVH)/2))
  168. }, completion: { (finish: Bool) in
  169. self.yearL.addSubview(self.pickerView)
  170. if self.pickerStyle == .datePicker {
  171. self.resetDateShow(date: Date())
  172. }
  173. })
  174. }
  175. }
  176. @objc private func close() {
  177. if animationStyle == .styleDefault {
  178. let ani = CAKeyframeAnimation(keyPath: "transform.translation.y")
  179. let currentTy = yearL.transform.ty
  180. ani.duration = 0.3
  181. ani.values = [currentTy, currentTy - 20, currentTy]
  182. ani.keyTimes = [0, 0.2, 0.1]
  183. ani.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
  184. yearL.layer.add(ani, forKey: "kViewShakerAnimationKey")
  185. var duraton = 0.21
  186. var y = -(margin + yearLH + sureVH) + 20
  187. if screenHeight == 812 {
  188. y -= 34
  189. duraton = 0.27
  190. }
  191. UIView.animate(withDuration: 0.3, delay: 0.3, usingSpringWithDamping: 0.3, initialSpringVelocity: 21, options: UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState, .layoutSubviews]), animations: {
  192. self.yearL.transform = CGAffineTransform(translationX: 0, y: y)
  193. })
  194. UIView.animate(withDuration: duraton, delay: 0.36, animations: {
  195. self.sureView.transform = CGAffineTransform.identity
  196. self.backgroundColor = .clear
  197. }) { (finish: Bool) in
  198. self.removeFromSuperview()
  199. }
  200. } else {
  201. UIView.animate(withDuration: 0.21, animations: {
  202. self.yearL.transform = CGAffineTransform.identity
  203. self.sureView.transform = CGAffineTransform.identity
  204. self.backgroundColor = .clear
  205. }, completion: { (finish: Bool) in
  206. self.removeFromSuperview()
  207. })
  208. }
  209. }
  210. @objc private func sureDate(_ button: UIButton) {
  211. var string = ""
  212. if pickerStyle == .datePicker {
  213. switch datePickerStyle {
  214. case .YMDHM:
  215. string = intentDate.formatterDate(formatter: "yyyy-MM-dd HH:mm")
  216. case .YMD:
  217. string = intentDate.formatterDate(formatter: "yyyy-MM-dd")
  218. case .MDHM:
  219. string = intentDate.formatterDate(formatter: "yyyy-MM-dd HH:mm")
  220. case .MD:
  221. string = intentDate.formatterDate(formatter: "yyyy-MM-dd")
  222. case .HM:
  223. string = intentDate.formatterDate(formatter: "yyyy-MM-dd HH:mm")
  224. }
  225. }
  226. if pickerStyle == .singlePicker {
  227. string = singleSelectedData
  228. }
  229. selectedBack?(string)
  230. close()
  231. }
  232. func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
  233. if touch.view != self {
  234. return false
  235. }
  236. return true
  237. }
  238. // MARK: - 配置滚轴
  239. func numberOfComponents(in pickerView: UIPickerView) -> Int {
  240. var num = 0
  241. if pickerStyle == .datePicker {
  242. switch datePickerStyle {
  243. case .YMDHM:
  244. num = 5
  245. case .YMD:
  246. num = 3
  247. case .MDHM:
  248. num = 4
  249. case .MD:
  250. num = 2
  251. case .HM:
  252. num = 2
  253. }
  254. }
  255. if pickerStyle == .singlePicker {
  256. num = 1
  257. }
  258. return num
  259. }
  260. func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  261. if pickerStyle == .datePicker {
  262. return getNumberOfRowsInComponent()[component]
  263. } else {
  264. return singlePickerDatas.count
  265. }
  266. }
  267. func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
  268. return 44
  269. }
  270. func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  271. let label = UILabel()
  272. label.textAlignment = NSTextAlignment.center
  273. var title = ""
  274. if pickerStyle == .datePicker {
  275. switch datePickerStyle {
  276. case .YMDHM:
  277. addLabel(tags: ["年", "月", "日", "时", "分"])
  278. if component == 0 {
  279. title = String(format: "%d", yearArray[row])
  280. }
  281. if component == 1 {
  282. title = String(format: "%02d", monthArray[row])
  283. }
  284. if component == 2 {
  285. title = String(format: "%02d", dayArray[row])
  286. }
  287. if component == 3 {
  288. title = String(format: "%02d", hourArray[row])
  289. }
  290. if component == 4 {
  291. title = String(format: "%02d", minuteArray[row])
  292. }
  293. case .YMD:
  294. addLabel(tags: ["年", "月", "日"])
  295. if component == 0 {
  296. title = String(format: "%d", yearArray[row])
  297. }
  298. if component == 1 {
  299. title = String(format: "%02d", monthArray[row])
  300. }
  301. if component == 2 {
  302. title = String(format: "%02d", dayArray[row])
  303. }
  304. case .MDHM:
  305. addLabel(tags: ["月", "日", "时", "分"])
  306. if component == 0 {
  307. title = String(format: "%02d", monthArray[row%12])
  308. }
  309. if component == 1 {
  310. title = String(format: "%02d", dayArray[row])
  311. }
  312. if component == 2 {
  313. title = String(format: "%02d", hourArray[row])
  314. }
  315. if component == 3 {
  316. title = String(format: "%02d", minuteArray[row])
  317. }
  318. case .MD:
  319. addLabel(tags: ["月", "日"])
  320. if component == 0 {
  321. title = String(format: "%02d", monthArray[row%12])
  322. }
  323. if component == 1 {
  324. title = String(format: "%02d", dayArray[row])
  325. }
  326. case .HM:
  327. addLabel(tags: ["时", "分"])
  328. if component == 0 {
  329. title = String(format: "%02d", hourArray[row])
  330. }
  331. if component == 1 {
  332. title = String(format: "%02d", minuteArray[row])
  333. }
  334. }
  335. }
  336. if pickerStyle == .singlePicker {
  337. title = singlePickerDatas[row]
  338. let view = UIView(frame: CGRect(x: 10, y: yearL.height/2 + 10, width: pickerView.width - 20, height: 0.5))
  339. view.backgroundColor = themeColor
  340. yearL.addSubview(view)
  341. }
  342. label.text = title
  343. return label
  344. }
  345. func addLabel(tags: [String]) {
  346. for subView in yearL.subviews {
  347. if subView is UILabel {
  348. subView.removeFromSuperview()
  349. }
  350. }
  351. let cellW: CGFloat = pickerView.width/CGFloat(tags.count)
  352. for i in 0..<tags.count {
  353. let labelX: CGFloat = cellW/4*3 + cellW*CGFloat(i)
  354. creatTagLabel(name: tags[i], x: labelX)
  355. }
  356. }
  357. func creatTagLabel(name: String, x: CGFloat) {
  358. let label = UILabel(frame: CGRect(x: x, y: yearL.height/2-15/2, width: 15, height: 15))
  359. label.text = name
  360. label.textAlignment = NSTextAlignment.center
  361. label.font = UIFont.systemFont(ofSize: 14)
  362. label.textColor = themeColor
  363. label.backgroundColor = .clear
  364. yearL.addSubview(label)
  365. }
  366. func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
  367. if pickerStyle == .datePicker {
  368. switch datePickerStyle {
  369. case .YMDHM:
  370. if component == 0 {
  371. yearIndex = row
  372. yearL.text = "\(yearArray[yearIndex])"
  373. }
  374. if component == 1 {
  375. monthIndex = row
  376. }
  377. if component == 2 {
  378. dayIndex = row
  379. }
  380. if component == 3 {
  381. hourIndex = row
  382. }
  383. if component == 4 {
  384. minuteIndex = row
  385. }
  386. if component == 0 || component == 1 {
  387. dayArray = daysInTheDate(year: yearArray[yearIndex], month: monthArray[monthIndex])
  388. if dayArray.count - 1 < dayIndex {
  389. dayIndex = dayArray.count - 1
  390. }
  391. }
  392. case .YMD:
  393. if component == 0 {
  394. yearIndex = row
  395. yearL.text = "\(yearArray[yearIndex])"
  396. }
  397. if component == 1 {
  398. monthIndex = row
  399. }
  400. if component == 2 {
  401. dayIndex = row
  402. }
  403. if component == 0 || component == 1 {
  404. dayArray = daysInTheDate(year: yearArray[yearIndex], month: monthArray[monthIndex])
  405. if dayArray.count - 1 < dayIndex {
  406. dayIndex = dayArray.count - 1
  407. }
  408. }
  409. case .MDHM:
  410. if component == 1 {
  411. dayIndex = row
  412. }
  413. if component == 2 {
  414. hourIndex = row
  415. }
  416. if component == 3 {
  417. minuteIndex = row
  418. }
  419. if component == 0 {
  420. yearChange(row: row)
  421. dayArray = daysInTheDate(year: yearArray[yearIndex], month: monthArray[monthIndex])
  422. if dayArray.count - 1 < dayIndex {
  423. dayIndex = dayArray.count - 1
  424. }
  425. }
  426. case .MD:
  427. if component == 1 {
  428. dayIndex = row
  429. }
  430. if component == 0 {
  431. yearChange(row: row)
  432. dayArray = daysInTheDate(year: yearArray[yearIndex], month: monthArray[monthIndex])
  433. if dayArray.count - 1 < dayIndex {
  434. dayIndex = dayArray.count - 1
  435. }
  436. }
  437. case .HM:
  438. if component == 0 {
  439. hourIndex = row
  440. }
  441. if component == 1 {
  442. minuteIndex = row
  443. }
  444. }
  445. pickerView.reloadAllComponents()
  446. let dateString = String(format: "%d-%d-%d %d:%d", yearArray[yearIndex], monthArray[monthIndex], dayArray[dayIndex], hourArray[hourIndex], minuteArray[minuteIndex])
  447. intentDate = dateString.toDate(formatter: "yyyy-MM-dd HH:mm")
  448. if intentDate.compare(minLimitDate!) == ComparisonResult.orderedAscending {
  449. intentDate = minLimitDate!
  450. resetDateShow(date: minLimitDate!)
  451. }
  452. if intentDate.compare(maxLimitDate!) == ComparisonResult.orderedDescending {
  453. intentDate = maxLimitDate!
  454. resetDateShow(date: maxLimitDate!)
  455. }
  456. }
  457. if pickerStyle == .singlePicker {
  458. singleSelectedData = singlePickerDatas[row]
  459. }
  460. }
  461. func yearChange(row: NSInteger) {
  462. monthIndex = row%12
  463. if (row - supMonthIndex) < 12 && (row - supMonthIndex) > 0
  464. && monthArray[monthIndex] < monthArray[supMonthIndex%12] {
  465. yearIndex += 1
  466. } else if (supMonthIndex - row) < 12 && (supMonthIndex - row) > 0
  467. && monthArray[monthIndex] > monthArray[supMonthIndex%12] {
  468. yearIndex -= 1
  469. } else {
  470. let interval = (row - supMonthIndex)/12
  471. yearIndex += interval
  472. }
  473. yearL.text = "\(yearArray[yearIndex])"
  474. supMonthIndex = row
  475. }
  476. // MARK: - 重置 Date 数据
  477. func resetDateShow(date: Date) {
  478. yearIndex = date.year - minYear
  479. monthIndex = date.month - 1
  480. dayIndex = date.day - 1
  481. hourIndex = date.hour
  482. minuteIndex = date.minute
  483. supMonthIndex = (intentDate.year - minYear)*12 + (intentDate.month - 1)
  484. var indexArray = [Int]()
  485. if datePickerStyle == .YMDHM {
  486. indexArray = [yearIndex, monthIndex, dayIndex, hourIndex, minuteIndex]
  487. }
  488. if datePickerStyle == .YMD {
  489. indexArray = [yearIndex, monthIndex, dayIndex]
  490. }
  491. if datePickerStyle == .MDHM {
  492. indexArray = [monthIndex, dayIndex, hourIndex, minuteIndex]
  493. }
  494. if datePickerStyle == .MD {
  495. indexArray = [monthIndex, dayIndex]
  496. }
  497. if datePickerStyle == .HM {
  498. indexArray = [hourIndex, minuteIndex]
  499. }
  500. if datePickerStyle == .HM {
  501. yearL.text = "\(Date().year)" + " " + "\(Date().month)" + " " + "\(Date().day)"
  502. } else {
  503. yearL.text = "\(yearArray[yearIndex])"
  504. }
  505. for i in 0..<indexArray.count {
  506. if (datePickerStyle == .MDHM || datePickerStyle == .MD) && i == 0 {
  507. pickerView.selectRow(supMonthIndex, inComponent: i, animated: true)
  508. pickerView(pickerView, didSelectRow: supMonthIndex, inComponent: i)
  509. } else {
  510. pickerView.selectRow(indexArray[i], inComponent: i, animated: true)
  511. pickerView(pickerView, didSelectRow: indexArray[i], inComponent: i)
  512. }
  513. }
  514. }
  515. // MARK: - 日期数据处理
  516. var maxLimitDate: Date?
  517. var minLimitDate: Date?
  518. let maxYear = Date().year + 60
  519. let minYear = Date().year - 60
  520. var intentDate = Date() // 设置要滚动到的意向日期,如默认日期、限制日期
  521. var yearArray = [Int]()
  522. var monthArray = [Int]()
  523. var dayArray = [Int]()
  524. var hourArray = [Int]()
  525. var minuteArray = [Int]()
  526. var yearIndex = 0
  527. var monthIndex = 0
  528. var dayIndex = 0
  529. var hourIndex = 0
  530. var minuteIndex = 0
  531. var supMonthIndex = 0 // 记录当前月所在所有年月中的位置
  532. func initDefaultDate() {
  533. for i in 0..<60 {
  534. if i > 0 && i <= 12 {
  535. monthArray.append(i)
  536. }
  537. if i < 24 {
  538. hourArray.append(i)
  539. }
  540. minuteArray.append(i)
  541. }
  542. for i in minYear..<maxYear {
  543. yearArray.append(i)
  544. }
  545. let caleddar = Calendar(identifier: Calendar.Identifier.gregorian)
  546. let component = Set<Calendar.Component>([.year, .month, .day, .hour, .minute])
  547. let comps = caleddar.dateComponents(component, from: Date())
  548. let year = comps.year
  549. if maxLimitDate == nil {
  550. maxLimitDate = String(format: "%ld-12-31 23:59", year! + 10).toDate(formatter: "yyyy-MM-dd HH:mm")
  551. }
  552. if minLimitDate == nil {
  553. minLimitDate = String(format: "%ld-01-01 00:00", year! - 10).toDate(formatter: "yyyy-MM-dd HH:mm")
  554. }
  555. }
  556. func getNumberOfRowsInComponent() -> [NSInteger] {
  557. dayArray = daysInTheDate(year: yearArray[yearIndex], month: monthArray[monthIndex])
  558. let timeInterval = maxYear - minYear
  559. var rows = [NSInteger]()
  560. switch datePickerStyle {
  561. case .YMDHM:
  562. rows = [yearArray.count, monthArray.count, dayArray.count, hourArray.count, minuteArray.count]
  563. case .YMD:
  564. rows = [yearArray.count, monthArray.count, dayArray.count]
  565. case .MDHM:
  566. rows = [monthArray.count*timeInterval, dayArray.count, hourArray.count, minuteArray.count]
  567. case .MD:
  568. rows = [monthArray.count*timeInterval, dayArray.count]
  569. case .HM:
  570. rows = [hourArray.count, minuteArray.count]
  571. }
  572. return rows
  573. }
  574. func daysInTheDate(year: NSInteger, month: NSInteger) -> [Int] {
  575. let isLeapYear = year%4==0 ? (year%100==0 ? (year%400==0 ? true : false) : true) : false
  576. var days = 0
  577. switch month {
  578. case 1, 3, 5, 7, 8, 10, 12:
  579. days = 31
  580. case 4, 6, 9, 11:
  581. days = 30
  582. case 2:
  583. if isLeapYear {
  584. days = 29
  585. } else {
  586. days = 28
  587. }
  588. default:
  589. break
  590. }
  591. var array = [Int]()
  592. for i in 1...days {
  593. array.append(i)
  594. }
  595. return array
  596. }
  597. }