UITableView - 如何在删除单元格时删除文件?
Posted
技术标签:
【中文标题】UITableView - 如何在删除单元格时删除文件?【英文标题】:UITableView - How to delete file while deleting cell? 【发布时间】:2017-10-17 04:20:48 【问题描述】:我在删除一个单元格时尝试删除一个 csv 文件,但是当我按下删除时出现下一个错误:
由于未捕获的异常“NSRangeException”而终止应用程序,原因:“* -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 2]' * 首先抛出调用栈:
代码:
//
/
/ CameraViewController.m
// oFiosstoryboard
//
// Created by Dorald on 24/05/15.
//
//
#import "CameraViewController.h"
#import "resultsDetailView.h"
@interface CameraViewController ()
@property (strong, nonatomic) IBOutlet UITableView *data;
@property (retain, nonatomic) IBOutlet UILabel *timeStamp;
@property (strong,nonatomic) NSMutableArray *dirList;
@property (nonatomic, assign) NSString *csvRow;
@property (nonatomic, strong) NSMutableArray *dataArray;
- (IBAction)didTapDeleteBtn:(id)sender;
@end
////////////////////////csv readder
NSMutableArray *tableDataArray;
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;
NSMutableArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *strPath = [[NSBundle mainBundle] pathForResource:@"file" ofType:@"csv"];
NSString *strFile = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
NSMutableArray *timeStampb = [[NSMutableArray alloc] init]; ;
NSMutableArray *arrayToDelete = [[NSMutableArray alloc] init]; ;
NSMutableArray *filePathsArray ;
//NSMutableArray *dirList= [[NSMutableArray alloc] init]; ;
NSString *currentcsvfile;
NSString *csvfilenameSave;
@implementation CameraViewController
@synthesize data;
- (void)viewDidLoad
[super viewDidLoad];
// ////lista de documentos
self.data.scrollEnabled = YES;
self.data.delegate = self;
self.data.dataSource = self;
//filePathsArray =[[NSMutableArray alloc] init]; ;
self.data.allowsMultipleSelectionDuringEditing = YES;
self.dataArray = [[NSMutableArray alloc]init];
NSInteger count = 100;
for (NSInteger i = count; i>=0; i--)
NSString *title = [NSString stringWithFormat:@"cell %ld",i];
[self.dataArray addObject:title];
NSMutableArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSMutableArray* fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
//--- Listing file by name sort
NSLog(@"\n File list %@",fileList);
//---- Sorting files by extension
NSMutableArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF EndsWith '.csv'"];
filePathsArray = [filePathsArray filteredArrayUsingPredicate:predicate];
NSLog(@"\n\n Sorted files by extension %@",filePathsArray);
self.dirList = [filePathsArray mutableCopy];
NSString *docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
if (!strFile)
NSLog(@"Error reading file.");
[timeStampb release];
timeStampb = [[NSMutableArray alloc] initWithArray:[strFile componentsSeparatedByString:@"\,"]];
// this .csv file is seperated with new line character
// if .csv is seperated by comma use "," instesd of "\n"
for(NSString *countryname in timeStampb)
NSLog(@"%@", timeStampb);
////////////////////////////////////////////////////////////////Delete csv files
//- (IBAction)delet:(id)sender
// NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
//
// NSString *filePath = [docPath stringByAppendingPathComponent:@"jorge.csv"];
// NSError *error = nil;
// [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
//
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
# pragma – mark table view DataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [self.dirList count];
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *simpleTableIdentifier = @"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier ];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
UIColor* color = [UIColor colorWithRed:(254.0/255.0) green:(251.0/255.0) blue:(248.0/255.0) alpha:1];
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor colorWithRed:(253.0/255.0) green:(0.0/255.0) blue:(237.0/255.0) alpha:1];
[cell setSelectedBackgroundView:bgColorView];
cell.backgroundColor = color;
cell.textLabel.text = [timeStampb objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [self.dirList objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor colorWithRed:(0.0/255.0) green:(0.0/255.0) blue:(0.0/255.0) alpha:1];
cell.textLabel.font=[UIFont systemFontOfSize:8.0];
cell.detailTextLabel.font=[UIFont systemFontOfSize:15.0];
cell.detailTextLabel.textColor = [UIColor colorWithRed:(235.0/255.0) green:(120.0/255.0) blue:(33.0/255.0) alpha:1];
return cell;
-(UITableViewCell *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSLog(@"%d", indexPath.row);
currentcsvfile = [self.dirList objectAtIndex:indexPath.row ];;
csvfilenameSave = [NSString stringWithFormat:currentcsvfile];
NSArray *paths3 = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory3 = [paths3 objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:@"%@/currentcsvnamefile.txt",
documentsDirectory3];
//create content - four lines of text
NSString *content =csvfilenameSave;
//save content to the documents directory
[content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy error:nil];
[_dirList addObject:_dirList[indexPath.row]];
NSLog(@"\n current csv csvfilenameSave % ",csvfilenameSave);
//[self performSegueWithIdentifier:@"detailsegue" sender:self];
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
// Update the delete button's title based on how many items are selected.
[_dirList removeObject:_dirList[indexPath.row]];
-(UITableViewCellEditingStyle)data:(UITableView *)data editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
return UITableViewCellEditingStyleDelete;
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
if ( editingStyle== UITableViewCellEditingStyleDelete)
[self.data deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[data setEditing:NO animated:YES];
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [docPath stringByAppendingPathComponent:[self.dirList objectAtIndex:indexPath.row ]];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
[_dirList removeObjectAtIndex:indexPath.row];
#pragma mark - UITableView Delegate Methods
//- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
//
// return UITableViewCellEditingStyleDelete;
//
#pragma mark - Delete Button Action
#pragma mark – TableView delegate
- (void)dealloc
[_timeStamp release];
[self.dirList release];
self.data.delegate = nil;
self.data.dataSource = nil;
[super dealloc];
@end
【问题讨论】:
显示您的阵列列表 -self.dirList
。把这行代码移到方法的最后:[_dirList removeObjectAtIndex:indexPath.row];
我成功使用的一种方法是监视目录的更改,并显示目录中的文件——独立于任何删除/重命名/创建操作。因此,当文件相关操作发生时,一旦更改反映在文件系统中,您的 TableView 就会更新。
为什么要从 didDeselectRowAtIndexPath
的数组中删除对象?
因为我需要删除与单元格中显示的名称匹配的文件。
更新表格时忘记添加-beginUpdates
和-endUpdates
;乍一看,这似乎是一个缺失的东西。
【参考方案1】:
实际上,您正在从顶部的数组中删除值。您必须在此函数结束时从数组中删除值。正如我在下面的代码中所做的那样,请检查我的答案并使用此代码,然后告诉我您是否遇到任何问题。我更新我的答案请再次检查。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
if ( editingStyle== UITableViewCellEditingStyleDelete)
currentcsvfile = [self.dirList objectAtIndex:indexPath.row];
csvfilenameSave = [NSString stringWithFormat:currentcsvfile];
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [docPath stringByAppendingPathComponent:csvfilenameSave];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
[_dirList removeObjectAtIndex:indexPath.row];
[self.data beginUpdates];
[self.data deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.data endUpdates];
[data setEditing:NO animated:YES];
【讨论】:
嗨!试一试,我得到这个错误:'NSInternalInconsistencyException',原因:'无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (4) 必须等于行数包含在更新之前的那个部分(4), @Alivajorg,现在你可以试试,我只是更新它。我同意我没有在我的答案中添加它。 @Alivajorg,如果您使用该数据源方法,您能否在问题中添加所有 tableview 代码,例如 tableview 中的行数和节数 当然,我只是粘贴完整的代码,感谢您的帮助。 尝试了代码并且有同样的错误。 csv 文件也是在其他视图中创建的。【参考方案2】:调用方法[self.data deleteRowsAtIndexPaths:withRowAnimation:];
会向tableview 发送一条消息以调整其显示,因此tableview 会抛出NSInternalInconsistencyException
,因为_dirList
计数不等于tableviews 行计数。
详情看这篇文章Inserting and Deleting Rows and Sections
您可以通过删除对应的项目来处理此问题
首先来自_dirList
数组的行,然后将 deleteRowsAtIndexPaths:withRowAnimation: 发送到表视图。
尝试替换- (void)tableView:(UITableView *)tableView commitEditingStyle
方法中的以下代码行:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
if ( editingStyle== UITableViewCellEditingStyleDelete)
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [docPath stringByAppendingPathComponent:[self.dirList objectAtIndex:indexPath.row ]];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
[_dirList removeObjectAtIndex:indexPath.row];
[self.data deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
希望它会起作用!
【讨论】:
以上是关于UITableView - 如何在删除单元格时删除文件?的主要内容,如果未能解决你的问题,请参考以下文章
删除 UITableView 中的最后一个单元格时索引超出范围
iOS 7 UITableView 问题 - 当我们已经有一个单元格时尝试设置滑动以删除单元格