WidgetViewController.m 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //
  2. // WidgetViewController.m
  3. // KulexiuForStudent
  4. //
  5. // Created by 王智 on 2022/9/13.
  6. //
  7. #import "WidgetViewController.h"
  8. #import "WidgetNavView.h"
  9. #import "WidgetDotView.h"
  10. #import "WidgetSpeedView.h"
  11. #import "WidgetFunctionView.h"
  12. #import "KSChoosePicker.h"
  13. #import "WidgetBottomButtonView.h"
  14. #import <AVFoundation/AVFoundation.h>
  15. #import "KSMetronomePlayer.h"
  16. @interface WidgetViewController ()<MetronomeControlViewDelegate,MetronomeFunctionDelegate>
  17. @property (nonatomic, strong) WidgetNavView *navView;
  18. @property (nonatomic, strong) WidgetDotView *dotView;
  19. @property (nonatomic, strong) WidgetSpeedView *speedView;
  20. @property (nonatomic, strong) WidgetFunctionView *functionView;
  21. @property (nonatomic, assign) int speed;
  22. @property (nonatomic, assign) KSWidgeMetronomeType metronomeType;
  23. @property (nonatomic, strong) KSChoosePicker *pickerView;
  24. @property (nonatomic, strong) WidgetBottomButtonView *bottomView;
  25. /** 定时器 */
  26. @property (nonatomic, strong) NSTimer *timer;
  27. /** 定时器多少秒循环一次 */
  28. @property (nonatomic, assign) float timerLength;
  29. @property (nonatomic, assign) int currentNo;
  30. @property (nonatomic, assign) NSInteger totalNoCount;
  31. @property (nonatomic, assign) float playVolume;
  32. @property (nonatomic, strong) KSMetronomePlayer *nodePlayer;
  33. @end
  34. @implementation WidgetViewController
  35. - (void)viewDidLoad {
  36. [super viewDidLoad];
  37. // Do any additional setup after loading the view.
  38. self.ks_prefersNavigationBarHidden = YES;
  39. [self configUI];
  40. [self setDefaultConfig];
  41. }
  42. - (void)backAction {
  43. [self removeAll];
  44. [self.navigationController popViewControllerAnimated:YES];
  45. }
  46. - (void)setDefaultConfig {
  47. self.speed = 90;
  48. self.playVolume = 1.0f;
  49. [self updateSpeedUI];
  50. self.metronomeType = KSWidgeMetronomeType4V4;
  51. [self changeBeat];
  52. self.functionView.volumeRate = 1.0f;
  53. }
  54. - (void)configUI {
  55. [self.scrollView removeFromSuperview];
  56. self.view.backgroundColor = HexRGB(0xECF9F7);
  57. [self.view addSubview:self.navView];
  58. [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
  59. make.left.right.top.mas_equalTo(self.view);
  60. make.height.mas_equalTo(kNaviBarHeight);
  61. }];
  62. [self.view addSubview:self.dotView];
  63. [self.dotView mas_makeConstraints:^(MASConstraintMaker *make) {
  64. make.left.right.mas_equalTo(self.view);
  65. make.top.mas_equalTo(self.navView.mas_bottom).offset(10);
  66. make.height.mas_equalTo(44);
  67. }];
  68. [self.view addSubview:self.speedView];
  69. [self.speedView mas_makeConstraints:^(MASConstraintMaker *make) {
  70. make.left.right.mas_equalTo(self.view);
  71. make.top.mas_equalTo(self.dotView.mas_bottom);
  72. make.height.mas_equalTo(300);
  73. }];
  74. [self.view addSubview:self.functionView];
  75. [self.functionView mas_makeConstraints:^(MASConstraintMaker *make) {
  76. make.left.right.mas_equalTo(self.view);
  77. make.top.mas_equalTo(self.speedView.mas_bottom);
  78. make.height.mas_equalTo(115);
  79. }];
  80. [self.view addSubview:self.bottomView];
  81. [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
  82. make.left.right.mas_equalTo(self.view);
  83. make.top.mas_equalTo(self.functionView.mas_bottom).offset(10);
  84. make.height.mas_equalTo(60);
  85. }];
  86. }
  87. #pragma mark --- delegate
  88. - (void)volumeChange:(float)volume {
  89. self.playVolume = volume;
  90. self.nodePlayer.volume = volume;
  91. }
  92. - (void)clickChangeBeat {
  93. // 显示节拍选择弹窗
  94. MJWeakSelf;
  95. self.pickerView = [[KSChoosePicker alloc] initWithTitle:@"节拍" sourceData:@[@"1/2",@"2/2",@"1/4",@"2/4",@"3/4",@"4/4",@"3/8",@"6/8"] chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
  96. KSWidgeMetronomeType type = chooseIndex;
  97. weakSelf.metronomeType = type;
  98. [weakSelf changeBeat];
  99. } cancel:^{
  100. }];
  101. [self.pickerView showPicker];
  102. }
  103. - (void)clickChangeSpeed:(int)speed {
  104. self.speed = speed;
  105. // 更新UI
  106. [self updateSpeedUI];
  107. }
  108. - (void)changeSpeedWithIsAdd:(BOOL)isAdd speed:(int)speed {
  109. if (isAdd) {
  110. self.speed = MIN(self.speed +speed, 200);
  111. }else{
  112. self.speed = MAX(self.speed -speed, 50);
  113. }
  114. // 更新UI
  115. [self updateSpeedUI];
  116. }
  117. - (void)updateSpeedUI {
  118. self.speedView.speed = self.speed;
  119. self.functionView.speed = self.speed;
  120. }
  121. #pragma mark --- lazying
  122. - (WidgetNavView *)navView {
  123. if (!_navView) {
  124. _navView = [WidgetNavView shareInstance];
  125. MJWeakSelf;
  126. [_navView navBackAction:^{
  127. [weakSelf backAction];
  128. }];
  129. }
  130. return _navView;
  131. }
  132. - (WidgetDotView *)dotView {
  133. if (!_dotView) {
  134. _dotView = [WidgetDotView shareInstance];
  135. }
  136. return _dotView;
  137. }
  138. - (WidgetSpeedView *)speedView {
  139. if (!_speedView) {
  140. _speedView = [WidgetSpeedView shareInstance];
  141. _speedView.delegate = self;
  142. }
  143. return _speedView;
  144. }
  145. - (WidgetFunctionView *)functionView {
  146. if (!_functionView) {
  147. _functionView = [WidgetFunctionView shareInstance];
  148. _functionView.delegate = self;
  149. }
  150. return _functionView;
  151. }
  152. - (WidgetBottomButtonView *)bottomView {
  153. if (!_bottomView) {
  154. _bottomView = [WidgetBottomButtonView shareInstance];
  155. MJWeakSelf;
  156. [_bottomView metronomePlayCallback:^(BOOL isPlay) {
  157. if (isPlay) {
  158. [weakSelf playBeat];
  159. }
  160. else {
  161. [weakSelf stopBeat];
  162. }
  163. }];
  164. }
  165. return _bottomView;
  166. }
  167. - (void)playBeat {
  168. // 重置
  169. self.currentNo = -1;
  170. // 开始播放
  171. [self.timer setFireDate:[NSDate distantPast]];
  172. [self.nodePlayer playAction:self.speed metronomeTyle:self.metronomeType];
  173. }
  174. - (void)stopBeat {
  175. [self.timer setFireDate:[NSDate distantFuture]];//暂停计时器
  176. [self.nodePlayer stopPlay];
  177. self.currentNo = -1;
  178. }
  179. - (void)changeBeat {
  180. [self.dotView updateSpotView:self.metronomeType];
  181. self.functionView.currentMetronomeType = self.metronomeType;
  182. self.speedView.currentType = self.metronomeType;
  183. }
  184. - (void)setSpeed:(int)speed {
  185. _speed = speed;
  186. CGFloat rateFloat = speed;
  187. self.timerLength = 1 / (rateFloat / 60);
  188. }
  189. - (KSMetronomePlayer *)nodePlayer {
  190. if (!_nodePlayer) {
  191. _nodePlayer = [[KSMetronomePlayer alloc] init];
  192. }
  193. return _nodePlayer;
  194. }
  195. - (NSTimer *)timer{
  196. if (!_timer) {
  197. _timer = [NSTimer scheduledTimerWithTimeInterval:self.timerLength target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
  198. [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
  199. }
  200. return _timer;
  201. }
  202. - (void)timerAction {
  203. [self.dotView updateSpotViewHeightState:self.currentNo];
  204. self.currentNo++;
  205. }
  206. #pragma mark -- 重置定时器
  207. - (void)resetTimer{
  208. [_timer invalidate];
  209. _timer = nil;
  210. [self.timer setFireDate:[NSDate distantPast]];
  211. }
  212. - (void)removeAll{
  213. if (_timer) {
  214. [_timer invalidate];
  215. _timer = nil;
  216. }
  217. }
  218. - (void)dealloc {
  219. NSLog(@"----dealloc ");
  220. [self removeAll];
  221. }
  222. /*
  223. #pragma mark - Navigation
  224. // In a storyboard-based application, you will often want to do a little preparation before navigation
  225. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  226. // Get the new view controller using [segue destinationViewController].
  227. // Pass the selected object to the new view controller.
  228. }
  229. */
  230. @end