recordViewController.m 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. //
  2. // recordViewController.m
  3. // 双子星云手机
  4. //
  5. // Created by xd h on 2025/3/28.
  6. //
  7. #import "recordViewController.h"
  8. #import "recordBottomView.h"
  9. #import "recordingView.h"
  10. #import <AVFoundation/AVFoundation.h>
  11. #import "recordFileModel.h"
  12. #import "recordFileCell.h"
  13. #import "reNameRecordFileView.h"
  14. #import "ComontAlretViewController.h"
  15. #import "editTypeHeadView.h"
  16. #import "recordEditBottomView.h"
  17. #import "uploadFileRecordViewController.h"
  18. @interface recordViewController ()<UITableViewDelegate,UITableViewDataSource,DZNEmptyDataSetSource, DZNEmptyDataSetDelegate,AVAudioPlayerDelegate>
  19. @property (nonatomic, strong) UIButton *rightButton;//编辑
  20. @property(nonatomic,strong) editTypeHeadView*curEditTypeHeadView;
  21. @property(nonatomic,strong) recordEditBottomView*curEditTypeBottomView;
  22. @property(nonatomic,strong) NSMutableArray* didSelectListArr;
  23. @property(nonatomic,assign) BOOL isEditType;
  24. @property (nonatomic, strong) UITableView *tableView;
  25. @property(nonatomic,strong)NSMutableArray *audioArr;//音频数据
  26. @property(nonatomic,strong)recordBottomView *recordBottomV;//底部视图
  27. @property(nonatomic,strong)recordingView *recordingV;//录音中
  28. @property(nonatomic,strong)reNameRecordFileView * reNameRecordFileV;
  29. @property(nonatomic,strong)AVAudioPlayer * curAudioPlayer;//音频播放器
  30. @property (strong, nonatomic) NSTimer *progressTimer;
  31. @property(nonatomic,strong) recordFileModel* curPlayerModel;//当前播放的音频数据
  32. @end
  33. @implementation recordViewController
  34. - (void)viewDidLoad {
  35. [super viewDidLoad];
  36. // Do any additional setup after loading the view.
  37. _audioArr = [NSMutableArray new];
  38. _didSelectListArr = [NSMutableArray new];
  39. [self drawAnyView];
  40. [self getRecordDataFun];
  41. }
  42. - (void)drawAnyView
  43. {
  44. [self.view setBackgroundColor:HWF5F7FAColor];
  45. self.navBarBGView.hidden = NO;
  46. [self.navigationBar setHidden:YES];
  47. [self.toolBar setHidden:YES];
  48. [self.titleLabel setText:NSLocalizedString(@"mine_record_title",nil)];
  49. self.navBarBGView.backgroundColor = [UIColor whiteColor];
  50. //编辑
  51. _rightButton = [[UIButton alloc] init];
  52. [_rightButton setTitle:NSLocalizedString(@"edit_common",nil) forState:UIControlStateNormal];
  53. [_rightButton setTitleColor:[UIColor hwColor:@"#01B7EA"] forState:UIControlStateNormal];
  54. _rightButton.titleLabel.font = [UIFont systemFontOfSize:14.0];
  55. _rightButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
  56. [_rightButton addTarget:self action:@selector(didClickEditFun) forControlEvents:UIControlEventTouchUpInside];
  57. [self.navBarBGView addSubview:_rightButton];
  58. [_rightButton mas_makeConstraints:^(MASConstraintMaker *make) {
  59. make.right.mas_equalTo(-15.f);
  60. make.width.mas_equalTo(40.f);
  61. make.centerY.equalTo(self.titleLabel.mas_centerY).offset(0.0);
  62. make.height.mas_equalTo(30);
  63. }];
  64. _curEditTypeHeadView = [[editTypeHeadView alloc] init];
  65. _curEditTypeHeadView.hidden = YES;
  66. [self.navBarBGView addSubview:_curEditTypeHeadView];
  67. [_curEditTypeHeadView mas_makeConstraints:^(MASConstraintMaker *make) {
  68. make.left.mas_equalTo(0);
  69. make.right.mas_equalTo(0);
  70. make.bottom.mas_equalTo(0);
  71. make.height.mas_equalTo(NAVIHEIGHT - AdaptNaviHeight);
  72. }];
  73. #pragma mark 编辑状态的 取消 和全选按钮 响应事件
  74. KWeakSelf
  75. _curEditTypeHeadView.didClickButtonFun = ^(NSInteger tag) {
  76. if(tag==1){
  77. [weakSelf userCancelEditTypeFun];
  78. }
  79. };
  80. _curEditTypeHeadView.didClickSelectAllFun = ^(UIButton * _Nonnull but) {
  81. [weakSelf didClickSelectAllButton:but];
  82. };
  83. _curEditTypeBottomView = [[recordEditBottomView alloc] init];
  84. _curEditTypeBottomView.hidden = YES;
  85. [self.view addSubview:_curEditTypeBottomView];
  86. [_curEditTypeBottomView mas_makeConstraints:^(MASConstraintMaker *make) {
  87. make.left.mas_equalTo(0);
  88. make.right.mas_equalTo(0);
  89. make.bottom.mas_equalTo(0);
  90. make.height.mas_equalTo(60 + AdaptTabHeight);
  91. }];
  92. #pragma mark 编辑状态的 下载 删除 响应事件
  93. _curEditTypeBottomView.didClickButtonFun = ^(NSInteger tag) {
  94. if(tag==1){
  95. [weakSelf gotoUpLoadFileFun];
  96. }
  97. else if(tag==3){
  98. [weakSelf showDeleteAlearViewFun];
  99. }
  100. };
  101. //底部视图
  102. _recordBottomV = [[recordBottomView alloc] init];
  103. [self.view addSubview:_recordBottomV];
  104. [_recordBottomV mas_makeConstraints:^(MASConstraintMaker *make) {
  105. make.left.mas_equalTo(0.f);
  106. make.right.mas_equalTo(0.f);
  107. make.bottom.mas_equalTo(0.f);
  108. make.height.mas_equalTo(100.f + AdaptTabHeight);
  109. }];
  110. //KWeakSelf
  111. _recordBottomV.didClickRecordFun = ^{
  112. [weakSelf didClickRecordFun];
  113. };
  114. [self.view addSubview:self.tableView];
  115. [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
  116. make.left.mas_equalTo(0);
  117. make.right.mas_equalTo(0);
  118. make.bottom.equalTo(self.recordBottomV.mas_top).offset(0.f);
  119. //make.bottom.mas_equalTo(0);
  120. make.top.equalTo(self.navBarBGView.mas_bottom).offset(10.f);
  121. }];
  122. }
  123. #pragma mark - 懒加载
  124. - (UITableView *)tableView{
  125. if (!_tableView) {
  126. _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H - TABBARHEIGHT) style:UITableViewStylePlain];
  127. _tableView.delegate = self;
  128. _tableView.dataSource = self;
  129. _tableView.showsVerticalScrollIndicator = NO;
  130. _tableView.showsHorizontalScrollIndicator = NO;
  131. // _tableView.contentInset = UIEdgeInsetsMake(-H_STATE_BAR, 0, 0, 0);
  132. [_tableView setSeparatorStyle:(UITableViewCellSeparatorStyleNone)];
  133. [_tableView setSeparatorColor:[UIColor clearColor]];
  134. [_tableView setBackgroundColor:[UIColor clearColor]];
  135. [_tableView setTableFooterView:[UIView new]];
  136. [_tableView setBounces:YES];
  137. if (@available(iOS 15.0, *)) {
  138. _tableView.sectionHeaderTopPadding = 0;
  139. }
  140. //空数据引入第三方开源处理
  141. _tableView.emptyDataSetSource = self;
  142. _tableView.emptyDataSetDelegate = self;
  143. // 下拉追加
  144. // MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
  145. // [self getMoreNetWorkData];
  146. // }];
  147. //
  148. // NSString *text = NSLocalizedString(@"NAS_bottom_tip",nil);
  149. // [footer setTitle:text forState:MJRefreshStateNoMoreData];
  150. // _tableView.mj_footer = footer;
  151. }
  152. return _tableView;
  153. }
  154. #pragma mark - 列表委托
  155. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  156. if(!_audioArr){
  157. return 0;
  158. }
  159. return _audioArr.count;
  160. }
  161. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  162. return 1;
  163. }
  164. - (recordFileCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  165. __block NSInteger row = indexPath.section;
  166. static NSString *identifier = @"recordFileCell";
  167. recordFileCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
  168. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  169. if (!cell){
  170. cell = [[recordFileCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
  171. [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
  172. [cell setBackgroundColor:[UIColor clearColor]];
  173. [cell setAccessoryType:(UITableViewCellAccessoryNone)];
  174. }
  175. if(row < _audioArr.count){
  176. recordFileModel* dataModel = _audioArr[row];
  177. cell.curRecordFileModel = dataModel;
  178. KWeakSelf
  179. cell.didClickRecordButFun = ^(NSInteger index) {
  180. [weakSelf didClickCellFunBy:index withRow:row];
  181. };
  182. cell.didClickSwitch = ^(BOOL SwitchOn) {
  183. [weakSelf userCheckFilePreviewByRow:row];
  184. };
  185. }
  186. return cell;
  187. }
  188. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
  189. NSInteger row = indexPath.section;
  190. if(row >=_audioArr.count){
  191. return 0.0;
  192. }
  193. recordFileModel *model = _audioArr[row];
  194. if (model.showAllType) {
  195. return 150;
  196. }
  197. return 65;
  198. }
  199. - (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
  200. {
  201. return [UIView new];
  202. }
  203. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
  204. return 12.0;
  205. }
  206. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  207. {
  208. if (_isEditType) {
  209. return;
  210. }
  211. NSInteger row = indexPath.section;
  212. if(row < _audioArr.count){
  213. recordFileModel *model = _audioArr[row];
  214. if(!model.showAllType){
  215. model.showAllType = YES;
  216. [tableView reloadData];
  217. }
  218. }
  219. }
  220. #pragma mark 空数据
  221. - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView {
  222. NSString *imageName = @"common_no_data_pic";
  223. return [UIImage imageNamed:imageName];
  224. }
  225. - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView {
  226. NSString *text = NSLocalizedString(@"record_no_data_tip",nil);
  227. NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:16.0f],
  228. NSForegroundColorAttributeName: HW999999Color};
  229. return [[NSAttributedString alloc] initWithString:text attributes:attributes];
  230. }
  231. //调整图片位置
  232. - (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView {
  233. return -150;
  234. }
  235. #pragma mark 读取本地数据
  236. - (void)getRecordDataFun
  237. {
  238. NSString *documentsDirectory = kSHPath_Record;
  239. NSFileManager *fileManager = [NSFileManager defaultManager];
  240. NSError *error = nil;
  241. NSArray *fileList = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:&error];
  242. if (error) {
  243. HLog(@"Error reading contents of directory: %@", error.localizedDescription);
  244. }
  245. NSMutableArray *dataArr = [NSMutableArray new];
  246. //BOOL isFirstType = YES;
  247. for (NSString *fileName in fileList) {
  248. NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
  249. // 获取文件属性
  250. NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:filePath error:&error];
  251. if (error) {
  252. NSLog(@"获取文件属性出错: %@ - %@", fileName, error.localizedDescription);
  253. error = nil;
  254. continue;
  255. }
  256. // 判断是否是目录
  257. BOOL isDirectory = [fileAttributes[NSFileType] isEqualToString:NSFileTypeDirectory];
  258. // 获取文件大小
  259. unsigned long long fileSize = [fileAttributes[NSFileSize] unsignedLongLongValue];
  260. recordFileModel *model = [recordFileModel new];
  261. model.fileName = fileName;
  262. model.filePath = filePath;
  263. model.fileSize = fileSize;
  264. model.isDirectory = isDirectory;
  265. model.modificationDate = fileAttributes[NSFileModificationDate] ?: [NSDate date];
  266. NSURL *fileUrl = [NSURL URLWithString:model.filePath];
  267. NSTimeInterval time = [self getDurationOfAudioFile:fileUrl];
  268. model.totalTime = (NSInteger)ceil(time); // 结果为 5;
  269. model.showAllType = NO;
  270. // if (isFirstType) {
  271. // model.showAllType = YES;
  272. // isFirstType = NO;
  273. // }
  274. // else{
  275. // model.showAllType = NO;
  276. // }
  277. // 创建文件信息字典
  278. // NSDictionary *fileInfo = @{
  279. // @"name": fileName,
  280. // @"path": filePath,
  281. // @"size": @(fileSize),
  282. // @"isDirectory": @(isDirectory),
  283. // @"modificationDate": fileAttributes[NSFileModificationDate] ?: [NSDate date]
  284. // };
  285. [dataArr addObject:model];
  286. }
  287. // 假设你的对象有一个名为 dateProperty 的 NSDate 属性
  288. NSArray *sortedArray = [dataArr sortedArrayUsingComparator:^NSComparisonResult(recordFileModel* obj1, recordFileModel* obj2) {
  289. return [obj2.modificationDate compare:obj1.modificationDate];
  290. }];
  291. [_audioArr removeAllObjects];
  292. [_audioArr addObjectsFromArray:sortedArray];
  293. recordFileModel *firstModel = _audioArr.firstObject;
  294. firstModel.showAllType = YES;
  295. }
  296. #pragma mark 获取录音文件的时长
  297. - (NSTimeInterval)getDurationOfAudioFile:(NSURL *)fileURL {
  298. NSError *error;
  299. AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
  300. if (error) {
  301. HLog(@"Error: %@", error.localizedDescription);
  302. return 0;
  303. }
  304. return player.duration;
  305. }
  306. #pragma mark 点击了录音
  307. - (void)didClickRecordFun
  308. {
  309. if(_recordingV){
  310. return;
  311. }
  312. //检测麦克风权限
  313. AVAudioSessionRecordPermission permissionStatus = [[AVAudioSession sharedInstance] recordPermission];
  314. // MicrophonePermissionStatus status;
  315. // switch (permissionStatus) {
  316. // case AVAudioSessionRecordPermissionUndetermined:
  317. // status = MicrophonePermissionStatusNotDetermined;
  318. // break;
  319. // case AVAudioSessionRecordPermissionDenied:
  320. // status = MicrophonePermissionStatusDenied;
  321. // break;
  322. // case AVAudioSessionRecordPermissionGranted:
  323. // status = MicrophonePermissionStatusGranted;
  324. // break;
  325. // }
  326. if (permissionStatus == AVAudioSessionRecordPermissionDenied) {
  327. NSString *tip = NSLocalizedString(@"mine_record_microphone_tip",nil);
  328. [[iToast makeText:tip] show];
  329. return;
  330. }
  331. else if(permissionStatus == AVAudioSessionRecordPermissionUndetermined) {
  332. KWeakSelf
  333. [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
  334. dispatch_async(dispatch_get_main_queue(), ^{
  335. if (granted) {
  336. [weakSelf beginRecordFun];
  337. } else {
  338. }
  339. });
  340. }];
  341. return;
  342. }
  343. [self beginRecordFun];
  344. }
  345. #pragma mark 弹起录音功能
  346. - (void)beginRecordFun
  347. {
  348. _recordingV = [[recordingView alloc] init];
  349. [ksharedAppDelegate.window addSubview:_recordingV];
  350. [_recordingV mas_makeConstraints:^(MASConstraintMaker *make) {
  351. make.left.mas_equalTo(0.f);
  352. make.right.mas_equalTo(0.f);
  353. make.bottom.mas_equalTo(0.f);
  354. make.top.mas_equalTo(0);
  355. }];
  356. NSInteger index = _audioArr.count + 1;
  357. [_recordingV beginRecordFunWith:index];
  358. KWeakSelf
  359. _recordingV.didClickRecordEndFun = ^{
  360. [weakSelf deleteRecordingViewFun];
  361. };
  362. }
  363. #pragma mark 删除录音中界面
  364. - (void)deleteRecordingViewFun
  365. {
  366. [_recordingV removeFromSuperview];
  367. _recordingV = nil;
  368. [self getRecordDataFun];
  369. [self.tableView reloadData];
  370. }
  371. #pragma mark 点击cell里面的按钮事件 //index 1 编辑 2 删除 10 播放(100 暂停) 11 后退 12 前进
  372. - (void)didClickCellFunBy:(NSInteger)index withRow:(NSInteger)row
  373. {
  374. switch (index) {
  375. case 1:
  376. [self didClickEditFunWithRow:row];
  377. break;
  378. case 2:
  379. [self deleteFileByRow:row];
  380. break;
  381. case 10:
  382. [self didClickPlayerByRow:row];
  383. break;
  384. case 11:
  385. [self playerBackwardFun];
  386. break;
  387. case 12:
  388. [self playerForwardFun];
  389. break;
  390. case 100://
  391. [self audioPlayerPauseFun];
  392. break;
  393. default:
  394. break;
  395. }
  396. }
  397. #pragma mark 点击编辑
  398. - (void)didClickEditFunWithRow:(NSInteger)row
  399. {
  400. recordFileModel *model = nil;
  401. if (_audioArr.count > row) {
  402. model = _audioArr[row];
  403. }
  404. else{
  405. return;
  406. }
  407. if (_reNameRecordFileV) {
  408. [_reNameRecordFileV removeFromSuperview];
  409. }
  410. _reNameRecordFileV = [[reNameRecordFileView alloc] init];
  411. [ksharedAppDelegate.window addSubview:_reNameRecordFileV];
  412. _reNameRecordFileV.fileName = model.fileName;
  413. [_reNameRecordFileV mas_makeConstraints:^(MASConstraintMaker *make) {
  414. make.left.mas_equalTo(0.0);
  415. make.right.mas_equalTo(0.0);
  416. make.top.mas_equalTo(0.0);
  417. make.bottom.mas_equalTo(0.0);
  418. }];
  419. KWeakSelf
  420. _reNameRecordFileV.didClickOkButtonFun = ^(NSString * _Nonnull newName) {
  421. [weakSelf checkRenameByNewName:newName withRow:row];
  422. };
  423. }
  424. #pragma mark 重命名逻辑
  425. - (void)checkRenameByNewName:(NSString*)newName withRow:(NSInteger)row
  426. {
  427. [_reNameRecordFileV removeFromSuperview];
  428. if (!newName || newName.length == 0) {
  429. NSString *tip = NSLocalizedString(@"record_reName_error_tip",nil);
  430. [[iToast makeText:tip] show];
  431. return;
  432. }
  433. recordFileModel *model = nil;
  434. if (_audioArr.count > row) {
  435. model = _audioArr[row];
  436. }
  437. else{
  438. return;
  439. }
  440. BOOL isRepeatType = NO;
  441. for (int i=0; i<_audioArr.count; i++) {
  442. if (i != row) {
  443. recordFileModel *preModel = _audioArr[i];
  444. if ([preModel.fileName isEqualToString:newName]) {
  445. isRepeatType = YES;
  446. break;
  447. }
  448. }
  449. }
  450. if (isRepeatType) {
  451. NSString *tip = NSLocalizedString(@"record_reName_error_repeat_tip",nil);
  452. [[iToast makeText:tip] show];
  453. return;
  454. }
  455. //[_reNameRecordFileV removeFromSuperview];
  456. // 获取文件管理器
  457. NSFileManager *fileManager = [NSFileManager defaultManager];
  458. // 原始文件路径
  459. NSString *documentsPath = kSHPath_Record;
  460. NSString *oldFilePath = [documentsPath stringByAppendingPathComponent:model.fileName];
  461. // 新文件路径
  462. NSString *newFilePath = [documentsPath stringByAppendingPathComponent:newName];
  463. NSError *error = nil;
  464. // 重命名/移动文件
  465. BOOL success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error];
  466. if (!success) {
  467. NSString *tip = NSLocalizedString(@"record_reName_error_title",nil);
  468. [[iToast makeText:tip] show];
  469. } else {
  470. NSString *tip = NSLocalizedString(@"record_reName_ok_title",nil);
  471. [[iToast makeText:tip] show];
  472. model.fileName = newName;
  473. [_tableView reloadData];
  474. }
  475. }
  476. #pragma mark 文件删除弹框
  477. - (void)showDeleteAlearViewFun
  478. {
  479. [self deleteFileByRow:-1];
  480. }
  481. #pragma mark 文件删除
  482. - (void)deleteFileByRow:(NSInteger)row
  483. {
  484. KWeakSelf
  485. /*弹窗提示重启*/
  486. ComontAlretViewController *nextVC = [[ComontAlretViewController alloc] initWithTiTle:NSLocalizedString(@"delete_file_title_msg",nil)
  487. msg:NSLocalizedString(@"delete_file_tip_msg",nil)
  488. imageStr:@""
  489. cancelTitle:NSLocalizedString(@"other_cancel",nil)
  490. okTitle:NSLocalizedString(@"delete_file_title_msg",nil) isOkBtnHighlight:YES
  491. didClickOk:^{
  492. [weakSelf sureDeleteFileByRow:row];
  493. } didClickCancel:^{
  494. }];
  495. nextVC.modalPresentationStyle = UIModalPresentationCustom;
  496. [self presentViewController:nextVC animated:YES completion:^{
  497. nextVC.view.superview.backgroundColor = [UIColor clearColor];
  498. }];
  499. }
  500. #pragma mark 文件删除
  501. - (void)sureDeleteFileByRow:(NSInteger)row
  502. {
  503. if (row == -1) {//删除编辑状态选中的旋转
  504. [self deleteSelectFileFun];
  505. return;
  506. }
  507. recordFileModel *model = nil;
  508. if (_audioArr.count > row) {
  509. model = _audioArr[row];
  510. }
  511. else{
  512. return;
  513. }
  514. NSFileManager *fileManager = [NSFileManager defaultManager];
  515. NSString *filePath = model.filePath; // 获取要删除的文件路径
  516. NSError *error = nil;
  517. BOOL success = [fileManager removeItemAtPath:filePath error:&error];
  518. if (!success) {
  519. //NSLog(@"删除文件失败: %@", error.localizedDescription);
  520. [[iToast makeText:NSLocalizedString(@"record_deleteFile_fail",nil)] show];
  521. } else {
  522. //NSLog(@"文件删除成功");
  523. [[iToast makeText:NSLocalizedString(@"delete_file_suc_msg",nil)] show];
  524. [_audioArr removeObject:model];
  525. recordFileModel *firstModel = _audioArr.firstObject;
  526. firstModel.showAllType = YES;
  527. [_tableView reloadData];
  528. }
  529. }
  530. #pragma mark 删除编辑状态选中的旋转
  531. - (void)deleteSelectFileFun
  532. {
  533. NSFileManager *fileManager = [NSFileManager defaultManager];
  534. for (recordFileModel*delModel in _didSelectListArr) {
  535. NSString *filePath = delModel.filePath; // 获取要删除的文件路径
  536. NSError *error = nil;
  537. BOOL success = [fileManager removeItemAtPath:filePath error:&error];
  538. if (!success) {
  539. //NSLog(@"删除文件失败: %@", error.localizedDescription);
  540. //[[iToast makeText:NSLocalizedString(@"record_deleteFile_fail",nil)] show];
  541. } else {
  542. //NSLog(@"文件删除成功");
  543. //[[iToast makeText:NSLocalizedString(@"delete_file_suc_msg",nil)] show];
  544. [_audioArr removeObject:delModel];
  545. }
  546. }
  547. // recordFileModel *firstModel = _audioArr.firstObject;
  548. // firstModel.showAllType = YES;
  549. [_tableView reloadData];
  550. [[iToast makeText:NSLocalizedString(@"delete_file_suc_msg",nil)] show];
  551. [_didSelectListArr removeAllObjects];
  552. [self setEditTypeTitleFun];
  553. }
  554. #pragma mark 点击了编辑按钮
  555. - (void)didClickEditFun
  556. {
  557. _isEditType = YES;
  558. _curEditTypeHeadView.hidden = NO;
  559. _curEditTypeBottomView.hidden = NO;
  560. _recordBottomV.hidden = YES;
  561. [self setEditTypeTitleFun];
  562. for (recordFileModel*model in _audioArr) {
  563. model.showAllType = NO;
  564. model.isEditType = YES;
  565. }
  566. [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
  567. make.left.mas_equalTo(0);
  568. make.right.mas_equalTo(0);
  569. make.bottom.mas_equalTo(_curEditTypeBottomView.mas_top);
  570. make.top.equalTo(self.navBarBGView.mas_bottom).offset(10.f);
  571. }];
  572. [self.tableView reloadData];
  573. }
  574. #pragma mark 用户取消编辑编辑
  575. - (void)userCancelEditTypeFun
  576. {
  577. //数据还原
  578. for (recordFileModel*model in _didSelectListArr) {
  579. model.isSelectType = NO;
  580. }
  581. [_didSelectListArr removeAllObjects];
  582. for (recordFileModel*model in _audioArr) {
  583. model.isEditType = NO;
  584. }
  585. recordFileModel*firstModel = _audioArr.firstObject;
  586. firstModel.showAllType = YES;
  587. _isEditType = NO;
  588. [self.tableView reloadData];
  589. _curEditTypeHeadView.hidden = YES;
  590. _curEditTypeBottomView.hidden = YES;
  591. _recordBottomV.hidden = NO;
  592. [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
  593. make.left.mas_equalTo(0);
  594. make.right.mas_equalTo(0);
  595. make.bottom.equalTo(self.recordBottomV.mas_top).offset(0.f);
  596. make.top.equalTo(self.navBarBGView.mas_bottom).offset(10.f);;
  597. }];
  598. }
  599. - (void)didClickSelectAllButton:(UIButton*)button
  600. {
  601. //button.selected = !button.selected;
  602. [_didSelectListArr removeAllObjects];
  603. for (recordFileModel* dataModel in _audioArr) {
  604. if(!button.selected){
  605. dataModel.isSelectType = button.selected;
  606. }
  607. else{
  608. [_didSelectListArr addObject:dataModel];
  609. dataModel.isSelectType = button.selected;
  610. }
  611. }
  612. [self.tableView reloadData];
  613. [self setEditTypeTitleFun];
  614. }
  615. - (void)userCheckFilePreviewByRow:(NSInteger)row
  616. {
  617. if(row < _audioArr.count){
  618. recordFileModel* dataModel = _audioArr[row];
  619. if(dataModel.isSelectType){
  620. [_didSelectListArr removeObject:dataModel];
  621. }
  622. else{
  623. [_didSelectListArr addObject:dataModel];
  624. }
  625. dataModel.isSelectType = !dataModel.isSelectType;
  626. [self setEditTypeTitleFun];
  627. }
  628. }
  629. #pragma mark 设置选中标题
  630. - (void)setEditTypeTitleFun
  631. {
  632. [_curEditTypeHeadView setTitleLabetextByNumbers:_didSelectListArr.count];
  633. if (_didSelectListArr.count > 0) {
  634. [_curEditTypeBottomView setButtonStateFunBy:YES];
  635. }
  636. else{
  637. [_curEditTypeBottomView setButtonStateFunBy:NO];
  638. }
  639. }
  640. #pragma mark 处理上传
  641. - (void)gotoUpLoadFileFun{
  642. if (_didSelectListArr.count <= 0) {
  643. return;
  644. }
  645. uploadFileRecordViewController *vc = [uploadFileRecordViewController new];
  646. [self.navigationController pushViewController:vc animated:YES];
  647. vc.isUploadingType = YES;
  648. [vc gotoUploadFileByRecord:_didSelectListArr];
  649. }
  650. #pragma mark 音频播放相关
  651. - (void)didClickPlayerByRow:(NSInteger)row
  652. {
  653. if(row > _audioArr.count){
  654. return;
  655. }
  656. recordFileModel* dataModel = _audioArr[row];
  657. NSURL* fileURL = [NSURL URLWithString:dataModel.filePath];
  658. _curPlayerModel = dataModel;
  659. for (recordFileModel*model in _audioArr) {
  660. model.isPlayingType = NO;
  661. }
  662. _curPlayerModel.isPlayingType = YES;
  663. if (_curAudioPlayer) {
  664. [_curAudioPlayer stop];
  665. _curAudioPlayer = nil;
  666. }
  667. NSError *error;
  668. _curAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
  669. _curAudioPlayer.delegate = self;
  670. _curAudioPlayer.currentTime = _curPlayerModel.curPlayerTime;
  671. [_curAudioPlayer play];//播放
  672. [self startProgressTimer];
  673. }
  674. #pragma mark 音频暂停播放
  675. - (void)audioPlayerPauseFun
  676. {
  677. [_curAudioPlayer pause];
  678. [self stopProgressTimer];
  679. }
  680. #pragma mark 播放代理
  681. - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
  682. {
  683. HLog(@"播放完成")
  684. [self stopProgressTimer];
  685. _curPlayerModel.isPlayingType = NO;
  686. _curPlayerModel.curPlayerTime = 0;// _curPlayerModel.totalTime;
  687. [self.tableView reloadData];
  688. }
  689. - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error
  690. {
  691. if (error) {
  692. HLog(@"解码失败")
  693. }
  694. }
  695. #pragma mark 播放进度相关
  696. - (void)startProgressTimer {
  697. [self stopProgressTimer];
  698. self.progressTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
  699. target:self
  700. selector:@selector(updateProgress)
  701. userInfo:nil
  702. repeats:YES];
  703. }
  704. - (void)stopProgressTimer {
  705. [self.progressTimer invalidate];
  706. self.progressTimer = nil;
  707. }
  708. - (void)updateProgress {
  709. if (_curPlayerModel.totalTime > _curPlayerModel.curPlayerTime) {
  710. _curPlayerModel.curPlayerTime += 1;
  711. }
  712. [self.tableView reloadData];
  713. }
  714. #pragma mark 向前15秒
  715. - (void)playerForwardFun
  716. {
  717. _curPlayerModel.curPlayerTime += 15;
  718. if (_curPlayerModel.curPlayerTime > _curPlayerModel.totalTime) {
  719. _curPlayerModel.curPlayerTime = _curPlayerModel.totalTime -2;
  720. }
  721. _curAudioPlayer.currentTime = _curPlayerModel.curPlayerTime;
  722. [self.tableView reloadData];
  723. }
  724. #pragma mark 向后15秒
  725. - (void)playerBackwardFun
  726. {
  727. _curPlayerModel.curPlayerTime -= 15;
  728. if (_curPlayerModel.curPlayerTime < 0) {
  729. _curPlayerModel.curPlayerTime = 0;
  730. }
  731. _curAudioPlayer.currentTime = _curPlayerModel.curPlayerTime;
  732. [self.tableView reloadData];
  733. }
  734. @end