BFIndirectionProgressView.swift 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //
  2. // BFIndirectionProgressView.swift
  3. // BFRecordScreenKit
  4. //
  5. // Created by SanW on 2021/12/18.
  6. // Copyright © 2021 BytesFlow. All rights reserved.
  7. //
  8. import BFCommonKit
  9. import BFMediaKit
  10. import UIKit
  11. class BFIndirectionProgressView: UIView {
  12. var indirecColor: UIColor = UIColor.clear
  13. var themeColor: UIColor = UIColor.hexColor(hexadecimal: "#28BE67")
  14. var progressHeight: CGFloat = 6
  15. var percenWidth: CGFloat = 0
  16. var totalDuration: Float64 = 0
  17. var currentItem: UIView? // 当前的Item
  18. override private init(frame: CGRect) {
  19. super.init(frame: frame)
  20. }
  21. init(frame: CGRect, indirecColor: UIColor = UIColor.clear, themeColor: UIColor = UIColor.hexColor(hexadecimal: "#28BE67"), percenWidth: CGFloat = 0, progressHeight: CGFloat = 6, totalDuration: Float64 = 0) {
  22. super.init(frame: frame)
  23. self.indirecColor = indirecColor
  24. self.themeColor = themeColor
  25. self.totalDuration = totalDuration
  26. self.progressHeight = progressHeight
  27. self.percenWidth = percenWidth
  28. if self.percenWidth <= 0, totalDuration > 0 {
  29. self.percenWidth = frame.width / totalDuration
  30. }
  31. }
  32. required init?(coder _: NSCoder) {
  33. fatalError("init(coder:) has not been implemented")
  34. }
  35. /// 重绘view
  36. /// - Parameter items: <#items description#>
  37. func resetAllSubViews(items: [PQVoiceModel]?, percenWidth: CGFloat = 0, totalDuration: Float64) {
  38. self.totalDuration = totalDuration
  39. self.percenWidth = percenWidth
  40. if self.percenWidth <= 0, totalDuration > 0 {
  41. self.percenWidth = frame.width / totalDuration
  42. }
  43. subviews.forEach { vv in
  44. vv.removeFromSuperview()
  45. }
  46. items?.forEach { model in
  47. _ = createItemView(minX: model.startTime * percenWidth, width: (model.endTime - model.startTime) * percenWidth)
  48. }
  49. }
  50. /// 设置进度
  51. /// - Parameters:
  52. /// - _: <#_ description#>
  53. /// - start: <#start description#>
  54. /// - progress: <#progress description#>
  55. func setProgress(start: CGFloat = 0, progress: Float64) {
  56. BFLog(message: "录音进度--指示器Indir:progress=\(progress),duration=\(totalDuration),w=\(frame.width),perW=\(percenWidth),totalW:\(progress * percenWidth)")
  57. detectionAndCreateItem(start: start, progress: progress)
  58. currentItem?.frame.size.width = progress < 0 ? 0 : progress * percenWidth
  59. BFLog(message: "当前view:\(String(describing: currentItem))")
  60. }
  61. /// 检测并创建item
  62. /// - Parameter start: <#start description#>
  63. func detectionAndCreateItem(start: CGFloat = 0, progress: Float64) {
  64. if currentItem == nil {
  65. currentItem = detectionItem(start: start, progress: progress)
  66. }
  67. }
  68. /// 检测当前view
  69. /// - Parameters:
  70. /// - start: <#start description#>
  71. /// - progress: <#progress description#>
  72. /// - Returns: <#description#>
  73. func detectionItem(start: CGFloat = 0, progress: Float64) -> UIView {
  74. let newRange = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 1000), end: CMTime(seconds: start + progress, preferredTimescale: 1000))
  75. var currentIndex: Int?
  76. for (index, item) in subviews.enumerated() {
  77. let originRange = CMTimeRange(start: CMTime(seconds: item.frame.minX / percenWidth, preferredTimescale: 1000), end: CMTime(seconds: item.frame.width / percenWidth, preferredTimescale: 1000))
  78. if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0 {
  79. currentIndex = index
  80. break
  81. }
  82. }
  83. if currentIndex != nil {
  84. BFLog(message: "检测存在重新创建")
  85. return subviews[currentIndex!]
  86. } else {
  87. BFLog(message: "检测不存在重新创建:\(start)")
  88. return createItemView(minX: start * percenWidth)
  89. }
  90. }
  91. /// 录制结束后重制当前item
  92. func resetCurrentItem(start: CGFloat, end: CGFloat) {
  93. currentItem?.frame.origin.x = start * percenWidth
  94. currentItem?.frame.size.width = (end - start) * percenWidth
  95. currentItem = nil
  96. }
  97. /// 删除某个view
  98. /// - Parameter index: <#index description#>
  99. func deleteItem(index: Int = 0) {
  100. if index >= 0, index < subviews.count {
  101. subviews[index].removeFromSuperview()
  102. }
  103. }
  104. /// 创建一个view
  105. /// - Parameters:
  106. /// - minX: <#minX description#>
  107. /// - width: <#width description#>
  108. /// - indirec: <#indirec description#>
  109. /// - Returns: <#description#>
  110. func createItemView(minX: CGFloat, width: CGFloat = 0, indirec: Bool = false) -> UIView {
  111. let lineV = UIView(frame: CGRect(x: minX < 0 ? 0 : minX, y: 0, width: width, height: progressHeight))
  112. lineV.backgroundColor = indirec ? indirecColor : themeColor
  113. addSubview(lineV)
  114. return lineV
  115. }
  116. }