QDatePicker.swift 25 KB

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