BFIndirectionProgressView.swift 5.4 KB

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