KSSpectrumView.m 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //
  2. // KSSpectrumView.m
  3. // KulexiuSchoolStudent
  4. //
  5. // Created by 王智 on 2024/7/29.
  6. //
  7. #import "KSSpectrumView.h"
  8. @interface KSSpectrumView ()
  9. @property (nonatomic, strong) CAGradientLayer *combinedGradientLayer;
  10. @end
  11. @implementation KSSpectrumView
  12. - (instancetype)initWithFrame:(CGRect)frame {
  13. self = [super initWithFrame:frame];
  14. if (self) {
  15. [self setupView];
  16. }
  17. return self;
  18. }
  19. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  20. self = [super initWithCoder:aDecoder];
  21. if (self) {
  22. [self setupView];
  23. }
  24. return self;
  25. }
  26. - (void)setupView {
  27. self.barWidth = 3.0;
  28. self.space = 1.0;
  29. self.combinedGradientLayer = [CAGradientLayer layer];
  30. self.combinedGradientLayer.colors = @[
  31. (__bridge id)HexRGBAlpha(0xffffff, 0.32f).CGColor,
  32. (__bridge id)HexRGBAlpha(0xffffff, 0.32f).CGColor
  33. ];
  34. self.combinedGradientLayer.locations = @[@0.6, @1.0];
  35. [self.layer addSublayer:self.combinedGradientLayer];
  36. }
  37. - (void)resetLayer {
  38. self.spectra = [NSArray array];
  39. }
  40. - (void)setSpectra:(NSArray<NSArray<NSNumber *> *> *)spectra {
  41. _spectra = spectra;
  42. if (spectra) {
  43. NSUInteger spectraCount = [spectra[0] count];
  44. NSMutableArray<NSNumber *> *combinedSpectrum = [NSMutableArray arrayWithCapacity:spectraCount];
  45. // 取两个声道数据中的最大值
  46. for (NSUInteger i = 0; i < spectraCount; i++) {
  47. NSNumber *leftAmplitude = spectra[0][i];
  48. NSNumber *rightAmplitude = spectra.count > 1 ? spectra[1][i] : @0;
  49. CGFloat maxAmplitude = MAX(leftAmplitude.floatValue, rightAmplitude.floatValue);
  50. [combinedSpectrum addObject:@(maxAmplitude)];
  51. }
  52. CGFloat viewHeight = self.bounds.size.height;
  53. CGFloat viewWidth = self.bounds.size.width;
  54. CGFloat middleY = viewHeight / 2.0;
  55. CGFloat barHeight = (viewHeight) / 2.0;
  56. CGFloat cornerRadius = viewWidth / 2.0f;
  57. CGFloat xIncrement = self.barWidth + self.space;
  58. UIBezierPath *combinedPath = [UIBezierPath bezierPath];
  59. // Left channel
  60. for (NSUInteger i = 0; i < spectraCount; i++) {
  61. CGFloat x = i * xIncrement + self.space;
  62. CGFloat amplitudeValue = combinedSpectrum[i].floatValue;
  63. CGFloat height = amplitudeValue * barHeight;
  64. CGFloat y = middleY - height/2.0; // Centered vertically
  65. CGRect rect = CGRectMake(x, y, self.barWidth, height);
  66. UIBezierPath *barPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
  67. [combinedPath appendPath:barPath];
  68. }
  69. CAShapeLayer *combinedMaskLayer = [CAShapeLayer layer];
  70. combinedMaskLayer.path = combinedPath.CGPath;
  71. self.combinedGradientLayer.frame = CGRectMake(0, 0, viewWidth, viewHeight);
  72. self.combinedGradientLayer.mask = combinedMaskLayer;
  73. }
  74. }
  75. - (CGFloat)translateAmplitudeToYPosition:(float)amplitude {
  76. CGFloat barHeight = amplitude * self.bounds.size.height;
  77. return self.bounds.size.height - barHeight;
  78. }
  79. - (void)dealloc {
  80. NSLog(@"---- KSSpectrumView dealloc");
  81. }
  82. /*
  83. // Only override drawRect: if you perform custom drawing.
  84. // An empty implementation adversely affects performance during animation.
  85. - (void)drawRect:(CGRect)rect {
  86. // Drawing code
  87. }
  88. */
  89. @end