JXSegmentedIndicatorLineView.swift 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // JXSegmentedIndicatorLineView.swift
  3. // JXSegmentedView
  4. //
  5. // Created by jiaxin on 2018/12/26.
  6. // Copyright © 2018 jiaxin. All rights reserved.
  7. //
  8. import UIKit
  9. public enum JXSegmentedIndicatorLineStyle {
  10. case normal
  11. case lengthen
  12. case lengthenOffset
  13. }
  14. open class JXSegmentedIndicatorLineView: JXSegmentedIndicatorBaseView {
  15. open var lineStyle: JXSegmentedIndicatorLineStyle = .normal
  16. /// lineStyle为lengthenOffset时使用,滚动时x的偏移量
  17. open var lineScrollOffsetX: CGFloat = 10
  18. open override func commonInit() {
  19. super.commonInit()
  20. indicatorHeight = 3
  21. }
  22. open override func refreshIndicatorState(model: JXSegmentedIndicatorParamsModel) {
  23. super.refreshIndicatorState(model: model)
  24. backgroundColor = indicatorColor
  25. layer.cornerRadius = getIndicatorCornerRadius(itemFrame: model.currentSelectedItemFrame)
  26. let width = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame)
  27. let height = getIndicatorHeight(itemFrame: model.currentSelectedItemFrame)
  28. let x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - width)/2
  29. var y = model.currentSelectedItemFrame.size.height - height - verticalOffset
  30. if indicatorPosition == .top {
  31. y = verticalOffset
  32. }
  33. frame = CGRect(x: x, y: y, width: width, height: height)
  34. }
  35. open override func contentScrollViewDidScroll(model: JXSegmentedIndicatorParamsModel) {
  36. super.contentScrollViewDidScroll(model: model)
  37. if model.percent == 0 || !isScrollEnabled {
  38. //model.percent等于0时不需要处理,会调用selectItem(model: JXSegmentedIndicatorParamsModel)方法处理
  39. //isScrollEnabled为false不需要处理
  40. return
  41. }
  42. let rightItemFrame = model.rightItemFrame
  43. let leftItemFrame = model.leftItemFrame
  44. let percent = model.percent
  45. var targetX: CGFloat = leftItemFrame.origin.x
  46. var targetWidth = getIndicatorWidth(itemFrame: leftItemFrame)
  47. let leftWidth = targetWidth
  48. let rightWidth = getIndicatorWidth(itemFrame: rightItemFrame)
  49. let leftX = leftItemFrame.origin.x + (leftItemFrame.size.width - leftWidth)/2
  50. let rightX = rightItemFrame.origin.x + (rightItemFrame.size.width - rightWidth)/2
  51. switch lineStyle {
  52. case .normal:
  53. targetX = JXSegmentedViewTool.interpolate(from: leftX, to: rightX, percent: CGFloat(percent))
  54. if indicatorWidth == JXSegmentedViewAutomaticDimension {
  55. targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: rightWidth, percent: CGFloat(percent))
  56. }
  57. case .lengthen:
  58. //前50%,只增加width;后50%,移动x并减小width
  59. let maxWidth = rightX - leftX + rightWidth
  60. if percent <= 0.5 {
  61. targetX = leftX
  62. targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: maxWidth, percent: CGFloat(percent*2))
  63. }else {
  64. targetX = JXSegmentedViewTool.interpolate(from: leftX, to: rightX, percent: CGFloat((percent - 0.5)*2))
  65. targetWidth = JXSegmentedViewTool.interpolate(from: maxWidth, to: rightWidth, percent: CGFloat((percent - 0.5)*2))
  66. }
  67. case .lengthenOffset:
  68. //前50%,增加width,并少量移动x;后50%,少量移动x并减小width
  69. let maxWidth = rightX - leftX + rightWidth - lineScrollOffsetX*2
  70. if percent <= 0.5 {
  71. targetX = JXSegmentedViewTool.interpolate(from: leftX, to: leftX + lineScrollOffsetX, percent: CGFloat(percent*2))
  72. targetWidth = JXSegmentedViewTool.interpolate(from: leftWidth, to: maxWidth, percent: CGFloat(percent*2))
  73. }else {
  74. targetX = JXSegmentedViewTool.interpolate(from:leftX + lineScrollOffsetX, to: rightX, percent: CGFloat((percent - 0.5)*2))
  75. targetWidth = JXSegmentedViewTool.interpolate(from: maxWidth, to: rightWidth, percent: CGFloat((percent - 0.5)*2))
  76. }
  77. }
  78. self.frame.origin.x = targetX
  79. self.frame.size.width = targetWidth
  80. }
  81. open override func selectItem(model: JXSegmentedIndicatorParamsModel) {
  82. super.selectItem(model: model)
  83. let targetWidth = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame)
  84. var toFrame = self.frame
  85. toFrame.origin.x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - targetWidth)/2
  86. toFrame.size.width = targetWidth
  87. if isScrollEnabled && (model.selectedType == .click || model.selectedType == .code) {
  88. //允许滚动且选中类型是点击或代码选中,才进行动画过渡
  89. UIView.animate(withDuration: scrollAnimationDuration, delay: 0, options: .curveEaseOut, animations: {
  90. self.frame = toFrame
  91. }) { (_) in
  92. }
  93. }else {
  94. frame = toFrame
  95. }
  96. }
  97. }