Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C: How to list files from documents directory into a UITableView?

Below I have some code that lists files from my documents directory into a UITableView. However, the code is not correctly working and once I test on my device even though there is files in the documents directory, nothing is listed all displayed just displaying some blank cells. Here is the code I am currently using:

NSArray *filePathsArray;

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [filePathsArray count];   
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"];
        if (cell == nil) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MainCell"];
        }
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory  error:nil];
        cell.textLabel.text = [documentsDirectory stringByAppendingPathComponent:[filePathsArray objectAtIndex:indexPath.row]];
        return cell;
    }
like image 914
user2536879 Avatar asked Jun 30 '13 17:06

user2536879


2 Answers

In your code, you are filling the array in cellForRowAtIndexPath:, and obviously

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

is called before cellForRowAtIndexPath. So you need to initialize the contents of the array before reloading table view. Either put the following lines in ViewDidLoad or viewWillAppear Methods:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory  error:nil];

And you should do handling like:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   if(!isDataLoading)  // if data loading has been completed, return the number of rows ELSE return 1
   {

       if ([filePathsArray count] > 0) 
          return [filePathsArray count];
       else 
          return 1;
    }

  return 1;
}

Note that I am returning a 1 when there are no files or when the data is loading, you can display a message like "Loading data..." or "No records found" in that cell. Make sure to set the userInteractionEnabled to NO for that cell else it may cause inconsistencies if the logic is not implemented properly.

like image 96
Jamal Zafar Avatar answered Oct 13 '22 19:10

Jamal Zafar


When tableView:numberOfRowsInSection: is called filePathsArray is nil, so 0 is returned from this method. Your code basically says "there are no rows in my tableView".
And the tableView does not ask for a cell if your tableView does not have any rows. So your method that fills the array is never called.

Move the following 3 lines of code into - (void)viewDidLoad or - (void)viewWillAppear:(BOOL)animated

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory  error:nil];
like image 43
Matthias Bauch Avatar answered Oct 13 '22 21:10

Matthias Bauch