上篇文章介绍了如何实现文件在tableView和collectionView中的显示,还有许多细节方面的东西有待补充。本文主要介绍如何实现对文件操作的可视化。
基本的编辑
对文件的编辑无外乎这几样:新建、删除、复制、剪切、粘贴、重命名。当然,又分为两种情况,单个文件操作与多个文件操作。这些方法都比较简单,直接上代码:
一、新建
-
新建文件夹
在这里我建议直接通过一个带有输入框的alertView来帮助用户新建文件夹
alert弹窗新建文件夹
还有些细节需要注意:
- 重名问题
- 文本输入的时候用户自己加了个点带个后缀
在这里只作为提醒,具体解决方法,我会在细节部分详细列出来
代码:
//新建文件夹
//弹出一个输入框
UIAlertController *addFiles = [UIAlertController alertControllerWithTitle:@"请输入文件夹名" message:nil preferredStyle:UIAlertControllerStyleAlert];
//输入文本框
[addFiles addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
}];
UIAlertAction *finished = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
if (addFiles.textFields.firstObject.text.length == 0) {
[SVProgressHUD showErrorWithStatus:@"文件夹名不能为空哦"];
return ;
}
//不为空,创建文件夹
//检查是否重名,重名就改名
NSString *dirName = [NSString changeFileNameWithCurrentPath:self.path FileName:addFiles.textFields.firstObject.text];
NSString *path = [self.path stringByAppendingPathComponent:dirName];
[XHHfileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
//通知当前文件夹刷新tableView
[self setdata:self.path];
[self.tableView reloadData];
[self.collectionView reloadData];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[addFiles addAction:finished];
[addFiles addAction:cancel];
[self presentViewController:addFiles animated:YES completion:nil];
- 新建文本文件
点击按钮以后跳转到一个textView页面,输入标题和内容,创建text文本文件。
通过这个方法来保存文本为一个txt格式的文件
当然要注意的细节仍然是重名问题
NSString *fileName = [NSString stringWithFormat:@"%@.txt",self.textTitle.text];
[self.atextView.text writeToFile:[self.path stringByAppendingPathComponent:fileName] atomically:YES encoding:NSUTF8StringEncoding error:nil];
- 至于其他文件,图片、视频、PDF文档、zip解压包等等,这些会在以后单独分享出来
二、删除
注意检查文件是否存在
注意统一使用多文件删除的方式
if (self.selectArray.count <1) {
[SVProgressHUD showErrorWithStatus:@"至少选择一个文件!"];
}
for (XHHFilesModel *model in self.selectArray) {
NSString *filePath = [self.path stringByAppendingPathComponent:model.fileName];
//这是关键方法
[XHHfileManager removeItemAtPath:filePath error:nil];
}
//刷新数据的时候会自动清除选中的项
[self refreshData];
三、重命名
此方法同样使用一个alert弹窗来重新设置名字
重名名方法相当于移动文件到新的路径
这个方法根据具体情况,可以集体重命名,当然重复的名字后面要加数字后缀
有个细节需要处理:在文本框显示文件名,同时光标移到后缀之前,并选中文件名字
//重命名
-(void)ChangeFilesName {
if (self.selectArray.count < 1 ) {
return;
}
//取出文件名
NSString *fileName = self.selectArray.firstObject.fileName;
NSLog(@"%@",fileName);
//弹出一个输入框
UIAlertController *addFiles = [UIAlertController alertControllerWithTitle:@"请输入文件名" message:nil preferredStyle:UIAlertControllerStyleAlert];
//输入文本框
[addFiles addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = fileName;
}];
UIAlertAction *finished = [UIAlertAction actionWithTitle:@"重命名" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
if (addFiles.textFields.firstObject.text.length == 0) {
[XHHSVProgressHUD showErrorWithStatus:@"文件名不能为空哦"];
return ;
}
NSMutableArray *filesNames = [NSMutableArray array];
[self.selectArray enumerateObjectsUsingBlock:^(XHHFilesModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//不为空,重命名
NSString *path = [self.path stringByAppendingPathComponent:obj.fileName];
//指向文件目录
NSLog(@"%@", addFiles.textFields.firstObject.text);
//修改后的名字加上文件后缀
NSString *fileNameBefore = addFiles.textFields.firstObject.text;
NSString *fileName2 = [NSString changeFileNameWithCurrentPath:self.path FileName:fileNameBefore];
NSString *filePath2= [self.path stringByAppendingPathComponent:fileName2];
//重命名的本质就是移动
[XHHfileManager moveItemAtPath:path toPath:filePath2 error:nil];
[filesNames addObject:fileName2];
}];
//通知当前文件夹刷新tableView
[self selectTheNewFilesCellWithFilesNameArray:filesNames];
}];
[addFiles addAction:finished];
[self presentViewController:addFiles animated:YES completion:nil];
}
重命名
四、复制、剪切、粘贴
这三个方法关联性强,也是一个小难点。
普通的一个文件从一个地方复制到同一个文件夹很好解决,那从一个文件夹复制到另一个呢?
因为一个页面就代表一个文件夹,所以两个不同文件夹会通过push按钮到不同文件夹
这就在可视化操作中相当于跨控制器操作,我的解决方法是:
- 用个人偏好设置来储存需要复制的文件数量、复制还是剪切属性、复制的文件路径 这三个方面。
- 在粘贴的时候读取key对应的值
- 粘贴完成后清空属性(当然在复制之前也做清空操作)
复制相关的代码(剪切的代码类似):
//这里再强调一下,因为复制粘贴都是全局的,不限控制器的,所以把需要复制或移动的文件信息存储到个人偏好设置中去
//复制
//确保最少选择一个
if (self.selectArray.count<1) {
[SVProgressHUD showErrorWithStatus:@"最少要选择一个文件哦"];
[self.selectArray removeAllObjects];
return;
}
//记录在个人偏好设置里
//是复制就存copy ,是移动,就存move
[XHHUserDefaults setObject:@"copy" forKey:MoveCopy];
[XHHUserDefaults setObject:@(self.selectArray.count) forKey:numMoveCopy];
for (int i = 0; i < self.selectArray.count ; i++ ) {
NSString *path = [self.path stringByAppendingPathComponent:self.selectArray[i].fileName];
//复制的内容不止一个,所以key键后面加数字区分
[XHHUserDefaults setObject:path forKey:[NSString stringWithFormat:@"%@%d",copyItem,i]];
}
[self.selectArray removeAllObjects];
粘贴相关的代码:
-(void)pasteFiles {
//粘贴
//确保最少选择一个
NSInteger theNumOfPast = 0;
NSMutableArray *fileNames = [NSMutableArray array];
if ([[XHHUserDefaults valueForKey:MoveCopy] isEqualToString:@"copy"]) {
//复制
//复制数量
NSInteger num = [[XHHUserDefaults valueForKey:numMoveCopy] integerValue];
theNumOfPast = num;
for (int i = 0; i < num ; i++ ) {
NSLog(@"%@",[XHHUserDefaults valueForKey:[NSString stringWithFormat:@"%@%d",copyItem,i]]);
//取出复制或移动之前的path
NSString *path = [XHHUserDefaults valueForKey:[NSString stringWithFormat:@"%@%d",copyItem,i]];
//检查是否重名
NSString *fileNameBefore = [NSString changeFileNameWithCurrentPath:self.path FileName:[path lastPathComponent]];
NSString *fileName = [NSString changeFileNameWithCurrentPath:self.path FileName:fileNameBefore];
[XHHfileManager copyItemAtPath:path toPath:[self.path stringByAppendingPathComponent:fileName] error:nil];
NSLog(@"%@",self.path);
NSLog(@"%@",[self.path stringByAppendingPathComponent:fileName]);
[fileNames addObject:fileName];
}
}else if ([[XHHUserDefaults valueForKey:MoveCopy] isEqualToString:@"move"]) {
//复制
//复制数量
NSInteger num = [[XHHUserDefaults valueForKey:numMoveCopy] integerValue];
theNumOfPast = num;
for (int i = 0; i < num ; i++ ) {
//取出复制或移动之前的path
NSString *path = [XHHUserDefaults valueForKey:[NSString stringWithFormat:@"%@%d",copyItem,i]];
//检查是否重名
NSString *fileName = [NSString changeFileNameWithCurrentPath:self.path FileName:[path lastPathComponent]];;
[XHHfileManager moveItemAtPath:path toPath:[self.path stringByAppendingPathComponent:fileName] error:nil];
NSLog(@"%@",[self.path stringByAppendingPathComponent:[path lastPathComponent]]);
[fileNames addObject:fileName];
}
}else {
[SVProgressHUD showErrorWithStatus:@"请您先选择一个粘贴对象"];
return;
}
[self selectTheNewFilesCellWithFilesNameArray:fileNames];
[XHHUserDefaults setObject:@"" forKey:MoveCopy];
[XHHUserDefaults setObject:@0 forKey:numMoveCopy];
[self.selectArray removeAllObjects];
}
复制和剪切在粘贴的时候唯一的区别就是是否删除原文件。当然二者有专门的方法可以操作,不用多说。
五、文件排序
文件的几种排序方式这个也很重要,需要借助到一个比较器。具体方法很简单又很实用:
//按创建时间排序
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(XHHFilesModel * _Nonnull first, XHHFilesModel * _Nonnull second) {
id firstData = first.NSFileCreationDate;
id secondData = second.NSFileCreationDate;//获取后一个文件
return [secondData compare:firstData];
其他的排序方式以此类推,相信难不倒聪明的你。
可视化菜单
当然,这一切操作的实现,都要通过一个具体的菜单来呈现,我用的是一个三方库CommonMenuView
,实现起来很简单,而且能够根据手指所点的位置显示出菜单,很不错,有空的时候我会好好分析一下源码,自己模仿着做一个。
//一个方法创建菜单:
[CommonMenuView createMenuWithFrame : CGRectZero
target : self.navigationController
dataArray : Array
itemsClickBlock : ^(NSString *str, NSInteger tag) { [weakSelf doSomething:(NSString *)str tag:(NSInteger)tag]; }
backViewTap : ^{ /* 点击背景遮罩view后的block,可自定义事件 */
[self.selectArray removeAllObjects];
}];
效果:
pop菜单
网友评论