UITableViw+Extension.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //
  2. // UITableView+Addtionss.swift
  3. // B2BAutoziMall
  4. //
  5. // Created by heew on 16/3/14.
  6. // Copyright © 2016年 qeegoo. All rights reserved.
  7. //
  8. import UIKit
  9. import ObjectiveC
  10. private var YWIndexViewKey:UInt8 = 0
  11. extension UITableView {
  12. var yw_index:YWIndexView? {
  13. set(indexView) {
  14. yw_index?.removeFromSuperview()
  15. objc_setAssociatedObject(self, &YWIndexViewKey, indexView, .OBJC_ASSOCIATION_ASSIGN)
  16. guard let _ = indexView else { return }
  17. // if indexView == yw_index { return }
  18. guard let controllerView:UIView = superview
  19. else { assertionFailure("tableView的父控件必须为控制器view"); return }
  20. layoutIndexView()
  21. controllerView.addSubview(indexView!)
  22. }
  23. get {
  24. return objc_getAssociatedObject(self, &YWIndexViewKey) as? YWIndexView
  25. }
  26. }
  27. private func layoutIndexView() {
  28. let tableViewH = bounds.size.height
  29. let tableViewW = bounds.size.width
  30. let tableViewY = frame.origin.y
  31. let tableViewInsetTop = contentInset.top
  32. let tableViewInsetBottom = contentInset.bottom
  33. let indexViewH = (tableViewH - tableViewInsetTop - tableViewInsetBottom) * 0.71
  34. let indexViewY = (tableViewH - tableViewInsetTop - tableViewInsetBottom) * 0.29 * 0.5 + tableViewY + tableViewInsetTop
  35. let indexViewW = CGFloat(55)
  36. let indexViewX = tableViewW - indexViewW
  37. let count = yw_index!.sectionTitles!.count
  38. yw_index!.frame = CGRect(x: indexViewX, y: indexViewY, width: indexViewW, height: indexViewH)
  39. for index in 0..<count {
  40. let letterLabel = yw_index!.subviews[index] as! UILabel
  41. let letterLabelX = CGFloat(0)
  42. let letterLabelH = indexViewH / CGFloat(count)
  43. let letterLabelY = letterLabelH * CGFloat(index)
  44. let letterLabelW = CGFloat(50)
  45. letterLabel.frame = CGRect(x: letterLabelX, y: letterLabelY , width: letterLabelW, height: letterLabelH)
  46. }
  47. let touch = UITapGestureRecognizer(target: self, action: #selector(UITableView.indexViewTap(tap:)))
  48. yw_index!.addGestureRecognizer(touch)
  49. let pan = UIPanGestureRecognizer(target: self, action: #selector(self.indexViewPan(pan:)))
  50. yw_index?.addGestureRecognizer(pan)
  51. }
  52. @objc func indexViewPan(pan:UIPanGestureRecognizer) {
  53. let indexView = pan.view as! YWIndexView
  54. let touchY = pan.location(in: pan.view).y
  55. let index = Int(touchY / indexView.bounds.height * CGFloat(indexView.sectionTitles!.count))
  56. if pan.state == .began { indexView.labelABC.isHidden = false }
  57. if pan.state == .ended { indexView.labelABC.isHidden = true }
  58. if index < 0 || index > numberOfSections - 1 { return }
  59. let indexPath = IndexPath(row: 0, section: index)
  60. if pan.state == .changed { scrollToRow(at: indexPath as IndexPath, at: .top, animated: false) }
  61. let letterLabel = yw_index!.subviews[index] as! UILabel
  62. indexView.labelABC.text = letterLabel.text
  63. }
  64. @objc func indexViewTap(tap: UITapGestureRecognizer) {
  65. let indexView = tap.view as! YWIndexView
  66. let touchY = tap.location(in: tap.view).y
  67. let index = Int(touchY / indexView.bounds.height * CGFloat(indexView.sectionTitles!.count))
  68. let indexPath = IndexPath(row: 0, section: index)
  69. scrollToRow(at: indexPath, at: .top, animated: true)
  70. let letterLabel = yw_index!.subviews[index] as! UILabel
  71. if tap.state == .began { letterLabel.backgroundColor = indexView.letterTrackingColor }
  72. if tap.state == .ended { letterLabel.backgroundColor = indexView.indexBgColor }
  73. }
  74. }
  75. class YWIndexView : UIView {
  76. var sectionTitles : [String]?
  77. var sectionIndexMinimumDisplayRowCount:Int = 2
  78. var letterColor = UIColor(red: 85.0/255.0, green: 141.0/255.0, blue: 215.0/255.0, alpha: 1)
  79. var letterFont : UIFont = UIFont.systemFont(ofSize: 12)
  80. var letterTrackingColor : UIColor = UIColor(red: 27 / 255.0, green: 61 / 255.0, blue: 249 / 255.0, alpha: 1)
  81. var indexBgColor : UIColor = UIColor.clear
  82. lazy var labelABC : UILabel = {
  83. let l = UILabel(frame:CGRect(x: 0 , y: 0 , width: 60, height: 60))
  84. self.window!.addSubview(l)
  85. l.font = UIFont.systemFont(ofSize: 32)
  86. l.textColor = UIColor.white
  87. l.backgroundColor = UIColor.darkGray
  88. l.textAlignment = .center
  89. l.layer.cornerRadius = 8
  90. l.clipsToBounds = true
  91. l.center.x = self.window!.center.x - 40
  92. l.center.y = self.window!.center.y
  93. return l
  94. }()
  95. class func IndexViewWith(sectionTitles:[String]?,letterColor:UIColor? = nil,letterFont:UIFont? = nil,letterTrackingColor:UIColor? = nil,sectionIndexMinimumDisplayRowCount:Int? = nil,indexBgColor:UIColor? = nil) ->YWIndexView? {
  96. let indexView = YWIndexView(frame: .zero)
  97. if let sectionTitles = sectionTitles { indexView.sectionTitles = sectionTitles }
  98. if let letterColor = letterColor { indexView.letterColor = letterColor }
  99. if let letterFont = letterFont { indexView.letterFont = letterFont }
  100. if let rowCount = sectionIndexMinimumDisplayRowCount {indexView.sectionIndexMinimumDisplayRowCount = rowCount }
  101. if let letterTrackingColor = letterTrackingColor { indexView.letterTrackingColor = letterTrackingColor }
  102. guard let sectionTitles = sectionTitles else { return nil }
  103. if sectionTitles.count < indexView.sectionIndexMinimumDisplayRowCount { return nil }
  104. sectionTitles.forEach{
  105. let letterLabel = UILabel(frame: .zero)
  106. letterLabel.text = $0
  107. letterLabel.textColor = indexView.letterColor
  108. letterLabel.font = indexView.letterFont
  109. letterLabel.textAlignment = .right
  110. indexView.addSubview(letterLabel)
  111. }
  112. return indexView
  113. }
  114. }