JXSegmentedIndicatorTriangleView.swift 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //
  2. // JXSegmentedIndicatorTriangleView.swift
  3. // JXSegmentedView
  4. //
  5. // Created by jiaxin on 2018/12/28.
  6. // Copyright © 2018 jiaxin. All rights reserved.
  7. //
  8. import UIKit
  9. open class JXSegmentedIndicatorTriangleView: JXSegmentedIndicatorBaseView {
  10. open override class var layerClass: AnyClass {
  11. return CAShapeLayer.self
  12. }
  13. private var path = UIBezierPath()
  14. open override func commonInit() {
  15. super.commonInit()
  16. indicatorWidth = 14
  17. indicatorHeight = 10
  18. }
  19. open override func refreshIndicatorState(model: JXSegmentedIndicatorParamsModel) {
  20. super.refreshIndicatorState(model: model)
  21. backgroundColor = nil
  22. let shapeLayer = self.layer as! CAShapeLayer
  23. shapeLayer.fillColor = indicatorColor.cgColor
  24. let width = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame)
  25. let height = getIndicatorHeight(itemFrame: model.currentSelectedItemFrame)
  26. let x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - width)/2
  27. var y = model.currentSelectedItemFrame.size.height - height - verticalOffset
  28. if indicatorPosition == .top {
  29. y = verticalOffset
  30. }
  31. frame = CGRect(x: x, y: y, width: width, height: height)
  32. path = UIBezierPath()
  33. if indicatorPosition == .bottom {
  34. path.move(to: CGPoint(x: 0, y: height))
  35. path.addLine(to: CGPoint(x: width/2, y: 0))
  36. path.addLine(to: CGPoint(x: width, y: height))
  37. }else {
  38. path.move(to: CGPoint(x: 0, y: 0))
  39. path.addLine(to: CGPoint(x: width/2, y: height))
  40. path.addLine(to: CGPoint(x: width, y: 0))
  41. }
  42. path.close()
  43. shapeLayer.path = path.cgPath
  44. }
  45. open override func contentScrollViewDidScroll(model: JXSegmentedIndicatorParamsModel) {
  46. super.contentScrollViewDidScroll(model: model)
  47. if model.percent == 0 || !isScrollEnabled {
  48. //model.percent等于0时不需要处理,会调用selectItem(model: JXSegmentedIndicatorParamsModel)方法处理
  49. //isScrollEnabled为false不需要处理
  50. return
  51. }
  52. let rightItemFrame = model.rightItemFrame
  53. let leftItemFrame = model.leftItemFrame
  54. let percent = model.percent
  55. let targetWidth = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame)
  56. let leftX = leftItemFrame.origin.x + (leftItemFrame.size.width - targetWidth)/2
  57. let rightX = rightItemFrame.origin.x + (rightItemFrame.size.width - targetWidth)/2
  58. let targetX = JXSegmentedViewTool.interpolate(from: leftX, to: rightX, percent: CGFloat(percent))
  59. self.frame.origin.x = targetX
  60. }
  61. open override func selectItem(model: JXSegmentedIndicatorParamsModel) {
  62. super.selectItem(model: model)
  63. let targetWidth = getIndicatorWidth(itemFrame: model.currentSelectedItemFrame)
  64. var toFrame = self.frame
  65. toFrame.origin.x = model.currentSelectedItemFrame.origin.x + (model.currentSelectedItemFrame.size.width - targetWidth)/2
  66. if isScrollEnabled && (model.selectedType == .click || model.selectedType == .code) {
  67. //允许滚动且选中类型是点击或代码选中,才进行动画过渡
  68. UIView.animate(withDuration: scrollAnimationDuration, delay: 0, options: .curveEaseOut, animations: {
  69. self.frame = toFrame
  70. }) { (_) in
  71. }
  72. }else {
  73. frame = toFrame
  74. }
  75. }
  76. }