123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- //
- // recordViewController.m
- // 双子星云手机
- //
- // Created by xd h on 2025/3/28.
- //
- #import "recordViewController.h"
- #import "recordBottomView.h"
- #import "recordingView.h"
- #import <AVFoundation/AVFoundation.h>
- #import "recordFileModel.h"
- #import "recordFileCell.h"
- @interface recordViewController ()<UITableViewDelegate,UITableViewDataSource,DZNEmptyDataSetSource, DZNEmptyDataSetDelegate>
- @property (nonatomic, strong) UITableView *tableView;
- @property(nonatomic,strong)NSMutableArray *audioArr;//音频数据
- @property(nonatomic,strong)recordBottomView *recordBottomV;//底部视图
- @property(nonatomic,strong)recordingView *recordingV;//录音中
- @end
- @implementation recordViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
-
- _audioArr = [NSMutableArray new];
- [self drawAnyView];
- [self getRecordDataFun];
- }
- - (void)drawAnyView
- {
- [self.view setBackgroundColor:HWF5F7FAColor];
- self.navBarBGView.hidden = NO;
- [self.navigationBar setHidden:YES];
- [self.toolBar setHidden:YES];
- [self.titleLabel setText:NSLocalizedString(@"mine_record_title",nil)];
-
- //底部视图
- _recordBottomV = [[recordBottomView alloc] init];
- [self.view addSubview:_recordBottomV];
- [_recordBottomV mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.mas_equalTo(0.f);
- make.right.mas_equalTo(0.f);
- make.bottom.mas_equalTo(0.f);
- make.height.mas_equalTo(100.f + AdaptTabHeight);
- }];
-
- KWeakSelf
- _recordBottomV.didClickRecordFun = ^{
- [weakSelf didClickRecordFun];
- };
-
- [self.view addSubview:self.tableView];
- [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.mas_equalTo(0);
- make.right.mas_equalTo(0);
- make.bottom.equalTo(self.recordBottomV.mas_top).offset(0.f);
- //make.bottom.mas_equalTo(0);
- make.top.equalTo(self.navBarBGView.mas_bottom).offset(10.f);
- }];
- }
- #pragma mark - 懒加载
- - (UITableView *)tableView{
- if (!_tableView) {
- _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H - TABBARHEIGHT) style:UITableViewStylePlain];
- _tableView.delegate = self;
- _tableView.dataSource = self;
- _tableView.showsVerticalScrollIndicator = NO;
- _tableView.showsHorizontalScrollIndicator = NO;
- // _tableView.contentInset = UIEdgeInsetsMake(-H_STATE_BAR, 0, 0, 0);
- [_tableView setSeparatorStyle:(UITableViewCellSeparatorStyleNone)];
- [_tableView setSeparatorColor:[UIColor clearColor]];
- [_tableView setBackgroundColor:[UIColor clearColor]];
- [_tableView setTableFooterView:[UIView new]];
- [_tableView setBounces:YES];
-
- if (@available(iOS 15.0, *)) {
- _tableView.sectionHeaderTopPadding = 0;
- }
-
- //空数据引入第三方开源处理
- _tableView.emptyDataSetSource = self;
- _tableView.emptyDataSetDelegate = self;
-
- // 下拉追加
- // MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
- // [self getMoreNetWorkData];
- // }];
- //
- // NSString *text = NSLocalizedString(@"NAS_bottom_tip",nil);
- // [footer setTitle:text forState:MJRefreshStateNoMoreData];
- // _tableView.mj_footer = footer;
- }
-
- return _tableView;
- }
- #pragma mark - 列表委托
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
- if(!_audioArr){
- return 0;
- }
- return _audioArr.count;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return 1;
- }
- - (recordFileCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- __block NSInteger row = indexPath.section;
- static NSString *identifier = @"recordFileCell";
-
- recordFileCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- if (!cell){
- cell = [[recordFileCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
- [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
- [cell setBackgroundColor:[UIColor clearColor]];
- [cell setAccessoryType:(UITableViewCellAccessoryNone)];
-
-
- }
-
- if(row < _audioArr.count){
- recordFileModel* dataModel = _audioArr[row];
- cell.curRecordFileModel = dataModel;
- //
- // KWeakSelf
- // cell.didClickSwitch = ^(BOOL SwitchOn) {
- // //if([weakSelf userCheckFileModel:dataModel withShowTip:YES]){
- // [weakSelf userCheckFilePreviewByRow:row];
- // //}
- // };
- }
- return cell;
- }
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
-
- NSInteger row = indexPath.section;
- if(row >=_audioArr.count){
- return 0.0;
- }
-
- recordFileModel *model = _audioArr[row];
- if (model.showAllType) {
- return 150;
- }
-
- return 65;
- }
- - (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
- {
- return [UIView new];
- }
- - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
- return 12.0;
- }
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- {
- NSInteger row = indexPath.section;
- if(row < _audioArr.count){
- recordFileModel *model = _audioArr[row];
- if(!model.showAllType){
- model.showAllType = YES;
-
- [tableView reloadData];
- }
- }
- }
- #pragma mark 空数据
- - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView {
-
- NSString *imageName = @"common_no_data_pic";
-
- return [UIImage imageNamed:imageName];
- }
- - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView {
- NSString *text = NSLocalizedString(@"record_no_data_tip",nil);
-
- NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:16.0f],
- NSForegroundColorAttributeName: HW999999Color};
-
- return [[NSAttributedString alloc] initWithString:text attributes:attributes];
- }
- //调整图片位置
- - (CGFloat)verticalOffsetForEmptyDataSet:(UIScrollView *)scrollView {
- return -150;
- }
- #pragma mark 读取本地数据
- - (void)getRecordDataFun
- {
- NSString *documentsDirectory = kSHPath_Record;
- NSFileManager *fileManager = [NSFileManager defaultManager];
-
- NSError *error = nil;
- NSArray *fileList = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:&error];
-
- if (error) {
- HLog(@"Error reading contents of directory: %@", error.localizedDescription);
- }
-
- [_audioArr removeAllObjects];
- BOOL isFirstType = YES;
-
- for (NSString *fileName in fileList) {
- NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
-
- // 获取文件属性
- NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:filePath error:&error];
- if (error) {
- NSLog(@"获取文件属性出错: %@ - %@", fileName, error.localizedDescription);
- error = nil;
- continue;
- }
-
- // 判断是否是目录
- BOOL isDirectory = [fileAttributes[NSFileType] isEqualToString:NSFileTypeDirectory];
-
- // 获取文件大小
- unsigned long long fileSize = [fileAttributes[NSFileSize] unsignedLongLongValue];
-
- recordFileModel *model = [recordFileModel new];
- model.fileName = fileName;
- model.filePath = filePath;
- model.fileSize = fileSize;
- model.isDirectory = isDirectory;
- model.modificationDate = fileAttributes[NSFileModificationDate] ?: [NSDate date];
-
- NSURL *fileUrl = [NSURL URLWithString:model.filePath];
- NSTimeInterval time = [self getDurationOfAudioFile:fileUrl];
- model.totalTime = (NSInteger)ceil(time); // 结果为 5;
-
- if (isFirstType) {
- model.showAllType = YES;
- isFirstType = NO;
- }
- else{
- model.showAllType = NO;
- }
-
- // 创建文件信息字典
- // NSDictionary *fileInfo = @{
- // @"name": fileName,
- // @"path": filePath,
- // @"size": @(fileSize),
- // @"isDirectory": @(isDirectory),
- // @"modificationDate": fileAttributes[NSFileModificationDate] ?: [NSDate date]
- // };
-
- [_audioArr addObject:model];
- }
-
- }
- #pragma mark 获取录音文件的时长
- - (NSTimeInterval)getDurationOfAudioFile:(NSURL *)fileURL {
- NSError *error;
- AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
- if (error) {
- HLog(@"Error: %@", error.localizedDescription);
- return 0;
- }
- return player.duration;
- }
- #pragma mark 点击了录音
- - (void)didClickRecordFun
- {
- if(_recordingV){
- return;
- }
-
- //检测麦克风权限
- AVAudioSessionRecordPermission permissionStatus = [[AVAudioSession sharedInstance] recordPermission];
-
- // MicrophonePermissionStatus status;
- // switch (permissionStatus) {
- // case AVAudioSessionRecordPermissionUndetermined:
- // status = MicrophonePermissionStatusNotDetermined;
- // break;
- // case AVAudioSessionRecordPermissionDenied:
- // status = MicrophonePermissionStatusDenied;
- // break;
- // case AVAudioSessionRecordPermissionGranted:
- // status = MicrophonePermissionStatusGranted;
- // break;
- // }
-
- if (permissionStatus == AVAudioSessionRecordPermissionDenied) {
- NSString *tip = NSLocalizedString(@"mine_record_microphone_tip",nil);
- [[iToast makeText:tip] show];
- return;
- }
- else if(permissionStatus == AVAudioSessionRecordPermissionUndetermined) {
- KWeakSelf
- [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (granted) {
- [weakSelf beginRecordFun];
- } else {
- }
- });
- }];
- return;
- }
-
-
- [self beginRecordFun];
-
- }
- #pragma mark 弹起录音功能
- - (void)beginRecordFun
- {
- _recordingV = [[recordingView alloc] init];
- [ksharedAppDelegate.window addSubview:_recordingV];
-
- [_recordingV mas_makeConstraints:^(MASConstraintMaker *make) {
- make.left.mas_equalTo(0.f);
- make.right.mas_equalTo(0.f);
- make.bottom.mas_equalTo(0.f);
- make.top.mas_equalTo(0);
- }];
-
- NSInteger index = _audioArr.count + 1;
- [_recordingV beginRecordFunWith:index];
-
- KWeakSelf
- _recordingV.didClickRecordEndFun = ^{
- [weakSelf deleteRecordingViewFun];
- };
- }
- #pragma mark 删除录音中界面
- - (void)deleteRecordingViewFun
- {
- [_recordingV removeFromSuperview];
- _recordingV = nil;
-
- [self getRecordDataFun];
- [self.tableView reloadData];
- }
- @end
|