UICollectionView not showing pictures [duplicate] - ios

This question already has an answer here:
Don't have the pictures from directory on CollectionView
(1 answer)
Closed 9 years ago.
I am showing the Pictures in all of the Directories however It does not display the pictures. I am putting NSLog in the code so that I can find out which code is working and I only get "j" in the log. I do not see the "a" in the log. What do you think is wrong?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *locations = [[NSArray alloc]initWithObjects:#"Bottoms", #"Dress", #"Coats", #"Others", #"hats", #"Tops",nil ];
NSString *fPath = documentsDirectory;
for(NSString *component in locations)
{
fPath = [fPath stringByAppendingPathComponent:component];
}
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionTrash.delegate =self;
collectionTrash.dataSource=self;
for(NSString *str in directoryContent){
NSLog(#"i");
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
}}
for(NSString *folder in locations) {
// get the folder contents
for(NSString *file in directoryContent) {
// load the image
}
}}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
NSLog(#"j");
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [allImagesArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseID = #"ReuseID";
TrashCell *mycell = (TrashCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseID forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[mycell viewWithTag:1];
imageInCell.image = [allImagesArray objectAtIndex:indexPath.row];
NSLog(#"a");
return mycell;
}
Feel free to as for more code.

If you look at the exception, it tells you very precisely what's wrong:
You are trying to calling a 'length' method on an array, which simply does not exist. You want to use count here instead. It's not in the code you posted, though - so just do a search for length and you'll probably find it rather easily if the project isn't huge.
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:locations]; gives you a warning, because locations is an array. Think about it - just doesn't make sense: which of its elements do you want to add to the path?
As I think about it, both errors probably relate to each other: You simply ignored the compile time error - or warning - for the fPath, and now the stringByAppendingPathComponent: method calls length on its parameter, which is a method of the expected NSString.
Bottom line: Do not ignore compiler warnings! If you fix those, you probably reduce crashes, too.

Related

Loading images in collection view from documents folder

I have a list of images in my resources folder that I want to load into a collection view
I have my images file names in an NSAarray from the documents directory.
.h
{
NSArray *fileList;
NSString * searchedImage;
}
.m
NSFileManager *filesm = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSArray *getFilelist= [filesm contentsOfDirectoryAtPath:[paths objectAtIndex:0] error:nil];
BOOL isDirectory;
for (searchedImage in getFilelist){
BOOL fileExistsAtPath = [[NSFileManager defaultManager] fileExistsAtPath:searchedImage isDirectory:&isDirectory];
if (fileExistsAtPath) {
if (isDirectory)
{
//Found Directory
}
}
if ([[searchedImage pathExtension] isEqualToString:#"png"]) {
//This is Image File with .png Extension
NSLog(#"directoryContents = %#",searchedImage);
}
}
//count files
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *pathsAmount = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
fileList= [fm contentsOfDirectoryAtPath:[pathsAmount objectAtIndex:0] error:nil];
int filesCount = [fileList count];
NSLog(#"filesCount:%d", filesCount);
UINib *cellNib = [UINib nibWithNibName:#"NibCell" bundle:nil];
[self.appliancesCollectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];
}
return self;
}
this reurns my image names correctly as 63293446.png, appliance63293447.png, appliance63293448.png, appliance63293449.png, etc in viewDidLoad
I want to load these into my collection view cells. Currently it returns a null value for my images file names when in the -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath method
What ive tried so far in addtion to researching on here
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return fileList.count;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cvCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.backgroundView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: [NSString stringWithFormat:#"%#",searchedImage]]];
NSLog(#"cell Bg image %#",searchedImage); <-----------------//returns null
return cell;
}
try this code
cell.backgroundView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: [NSString stringWithFormat:#"%#",[fileList objectAtIndex:indexPath.row]]]];
make sure searchedImage is not nil.
The file name of the image is in your fileList array, not in searchedImage, (this last variable is useless when creating the image).
NSString *fileName = [fileList objectAtIndex:indexPath.row];
cell.backgroundView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: fileName]];
The problem here is that in your code, fileList can contain files that are not images, thus imageNamed: will fail, and return nil. You should filter your fileList array, and make sure it contains only images.
At first make fileList mutable via NSMutableArray *fileList;
next in block add image path to fileList
if ([[searchedImage pathExtension] isEqualToString:#"png"]) {
//This is Image File with .png Extension
NSLog(#"directoryContents = %#",searchedImage);
[fileList addObject:searchedImage]
}
then in cellForItemAtIndexPath: set image with
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[fileList objectAtIndex:indexPath.row]]];

Crash when try to delete picture

I just want the user to just delete a picture by just tapping the picture using a collection view. I am doing this for a month and can't get things straight and even getting confused. My code for to do this is below. I am also getting a memory warning sometimes aswell, If i use the instruments app to look for detail the memory allocation does not get freed and just builds up until crash.
- (void)viewDidLoad
{  Trash = [NSMutableArray array];
filenames = [NSMutableArray new];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *locationStrings = [[NSArray alloc]initWithObjects:#"Bottoms", #"Dress", #"Coats", #"Others", #"hats", #"Tops",nil ];
for(NSString* location in locationStrings){
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSError *error;
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fPath error:&error];
collectionTrash.delegate =self;
collectionTrash.dataSource=self;
for(NSString *str in directoryContent){
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
[filenames addObject:finalFilePath];
}
}
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
NSLog(#"j");
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [filenames count];
NSLog(#"b");
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"ReuseID";
TrashCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[cell viewWithTag:1];
NSString *cacheKey = filenames[indexPath.item];
imageInCell.image = [self.imageCache objectForKey:cacheKey];
if (imageInCell.image == nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [UIImage imageWithContentsOfFile:filenames[indexPath.item]];
if (image) {
[self.imageCache setObject:image forKey:cacheKey];
dispatch_async(dispatch_get_main_queue(), ^{
TrashCell *updateCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[updateCell viewWithTag:1];
imageInCell.image = image;
});
}
});
}
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"s:%d", [Trash count]);
NSString *trashBin = [Trash objectAtIndex:indexPath.row];
NSLog(#"k%#l",trashBin);
[filenames removeObjectAtIndex:indexPath.row];
[Trash removeObjectAtIndex:indexPath.row];
[self deleteMyFiles:trashBin];
[collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]];
}
NSString *myFileName;
-(void) deleteMyFiles:(NSString*)filePath {
NSError *error;
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
} else {
NSLog(#"%#",filePath);
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[self.imageCache removeAllObjects];
}
When I try to tap a log comes out saying below.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(0x30afbe83 0x3ae5c6c7 0x30a31d95 0x638e9 0x3349d76f 0x3349d495 0x33406ea3 0x33406ea3 0x332781a1 0x332af9fd 0x332af3ab 0x33284d79 0x33283569 0x30ac6f1f 0x30ac63e7 0x30ac4bd7 0x30a2f471 0x30a2f253 0x357632eb 0x332e4845 0x628a5 0x3b355ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
Your Trash array not content any objects.
And you are trying to access object from Trash array
NSString *trashBin = [Trash objectAtIndex:indexPath.row];
Which is the cause of crash.
Note: object name should start with small letters.
In your code, Trash = [NSMutableArray array]; will be autoreleased at some time, so when you access it in '-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath', it has been released. If you are sure there is reason to use this variable instead of using only filenames, you can do this Trash = [[NSMutableArray array] retain]; or Trash = [[NSMutableArray alloc] init]; in your '- (void)viewDidLoad'.
It is not clear what you are trying to do. The notion of "Trash" suggests you are trying to implement a two-stage delete: put items in the trash and at some later time, empty the trash (delete them for good when the user selects an "Empty the Trash" button). But your post and your code suggest a single-stage delete (the user selects to delete with no chance to undo).
Your collectionView:didSelectItemAtIndexPath: delegate method looks particularly confused. As Bhumeshwer correctly points out, your Trash is empty and trying to access any index is causing your crash. No where in this code are you putting anything in Trash But, by simply removing that line of code, I don't think the method will do what you want.
If you are implementing a two-stage delete, I think you simply want to remove the string from filenames and add it to Trash. Don't remove the object from Trash and don't delete files in Trash. Somewhere else (like when the "Empty the Trash" button is selected), call deleteMyFiles to empty the trash.
If you are implementing a single-stage delete, get rid to Trash all together: don't allocate it in viewDidLoad and don't empty it in didSelectItemAtIndexPath. Simply, remove the object from filenames AND update the imageInCell!
Suggestions:
move
collectionTrash.delegate =self;
collectionTrash.dataSource=self;
to wherever collectionTrash is being created and initialized. Inside viewDidLoad and inside the for loop, it is out of context. Your mixing unrelated lines of code making your code unorganized and confusing. At least, move it out of the for loop.
think model-view-controller. What's the model here? Is it filenames or Trash? Is the CollectionView a view of filenames or Trash? What is collectionTrash?
Trash should be trash (as Bhumeshwer points out);
what is NSString *myFileName; and what's it doing there?
don't forget to manage your imageCache. You put images in but don't take them out. When you remove a file from filenames, remove the image from imageCache.
I could go on, but will stop here. Good luck.

Loading images only when needed

When I load the images to show to the UICollectionView I load all the images from the array like this
- (void)viewDidLoad
{
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Others";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionOthers.delegate =self;
collectionOthers.dataSource=self;
for(NSString *str in directoryContent)
{
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
image = nil;
}
finalFilePath=nil;
data=nil;
}
paths= nil;
documentsDirectory= nil;
location= nil;
fPath= nil;
directoryContent = nil;
}
This is the biggest issue in my app since it uses so many memory. It is because number and size of the images, this could just take up memory. I would only want to load images when they are needed, and discard them when they are no longer needed.However I do not know where and how to change my code so that it will be that way. I am doing this for three month or so and I really need help.
Update
This is my code for the specific part
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseID = #"ReuseID";
OthersCell *mycell = (OthersCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseID forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[mycell viewWithTag:1];
imageInCell.image = [allImagesArray objectAtIndex:indexPath.row];
NSLog(#"a");
return mycell;
}
Clearly, you should load the images just-in-time. One should never hold an array of images (because they take up a lot of memory), but rather just hold an array of filenames. So I'm suggesting you retire allImagesArray and instead define a NSMutableArray called filenames. You could then create the UIImage objects on the fly:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
OthersCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[cell viewWithTag:1];
imageInCell.image = [UIImage imageWithContentsOfFile:filenames[indexPath.item]];
return cell;
}
This, assumes, of course, that you populated this NSMutableArray of filenames in viewDidLoad:
- (void)viewDidLoad
{
filenames = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Others";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionOthers.delegate =self;
collectionOthers.dataSource=self;
for(NSString *str in directoryContent)
{
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
[filenames addObject:fileFilePath];
}
}
This has a problem, though, because imageWithContentsOfFile (as well as loading it into a NSData first and then doing imageWithData) is a bit slow if the images aren't tiny. On slower devices, this can result in a slight stuttering of a quick scroll of a collection view. So, a better approach would be to (a) load the images asynchronously; (b) use a NSCache to optimize performance for when you scroll backwards.
So, first, define a cache:
#property (nonatomic, strong) NSCache *imageCache;
And, instantiate this in viewDidLoad:
self.imageCache = [[NSCache alloc] init];
self.imageCache.name = #"com.company.app.imageCache";
And then, cellForItemAtIndexPath can (a) set the image from the cache; and (b) if not found, retrieve the image asynchronously updating cache and cell appropriately, e.g.:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
OthersCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[cell viewWithTag:1];
NSString *cacheKey = filenames[indexPath.item];
imageInCell.image = [self.imageCache objectForKey:cacheKey];
if (imageInCell.image == nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [UIImage imageWithContentsOfFile:filenames[indexPath.item]];
if (image) {
[self.imageCache setObject:image forKey:cacheKey];
dispatch_async(dispatch_get_main_queue(), ^{
OthersCell *updateCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
        UIImageView *imageInCell = (UIImageView*)[updateCell viewWithTag:1];
imageInCell.image = image;
});
}
});
}
return cell;
}
And, obviously, make sure you purge the cache if you receive memory warnings (in iOS 7, the cache doesn't always automatically purge itself under pressure like it used to do):
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[self.imageCache removeAllObjects];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
This is the method in which you should be loading the images.
In viewDidLoad, I'd build the array of NSString file paths to each image, then I'd use the collectionView:cellForItemAtIndexPath: method to load the image from the specific file path for this particular cell.
In viewDidLoad You could just load a list of available images. So remove the for loop: for(NSString *str in directoryContent) { ... } loop there (EDIT: or make it a simple for loop, just to populate an array with filenames for the files having data).
When you update a specific collectionviewcell in collectionView:cellForItemAtIndexPath:, just load the image (only 1). The cell will now hold the image data instead of your view controller. So when the cell is released, so is the image data.

Warning where I cannot clear [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have an error saying Incompatible pointer types sending NSArray to parameter of NSString. I also have used instruments and is very weird that as soon as my app start its around 90mb in memory. What is wrong with my code.
#interface TrashViewController ()
#end
#implementation TrashViewController {
NSMutableArray *Trash ;
}
#synthesize collectionTrash;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
filenames = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *locations = [[NSArray alloc]initWithObjects:#"Bottoms", #"Dress", #"Coats", #"Others", #"hats", #"Tops",nil ];
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:locations];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionTrash.delegate =self;
collectionTrash.dataSource=self;
for(NSString *str in directoryContent)
{
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
[filenames addObject:finalFilePath];
}
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
NSLog(#"j");
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [filenames count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"ReuseID";
TrashCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[cell viewWithTag:1];
NSString *cacheKey = filenames[indexPath.item];
imageInCell.image = [self.imageCache objectForKey:cacheKey];
if (imageInCell.image == nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [UIImage imageWithContentsOfFile:filenames[indexPath.item]];
if (image) {
[self.imageCache setObject:image forKey:cacheKey];
dispatch_async(dispatch_get_main_queue(), ^{
TrashCell *updateCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[updateCell viewWithTag:1];
imageInCell.image = image;
});
}
});
}
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"s:%d", [Trash count]);
NSString *trashBin = [Trash objectAtIndex:indexPath.row];
NSLog(#"k%#l",trashBin);
[filenames removeObjectAtIndex:indexPath.row];
[Trash removeObjectAtIndex:indexPath.row];
[self deleteMyFiles:trashBin];
[collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]];
}
NSString *myFileName;
-(void) deleteMyFiles:(NSString*)filePath {
NSError *error;
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
} else {
NSLog(#"%#",filePath);
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[self.imageCache removeAllObjects];
}
eYour problem is in line 5 of viewDidLoad. The method signature for -stringByAppendingPathComponent is
- (NSString *)stringByAppendingPathComponent:(NSString *)aString
Note that it expects a String, but you are passing an Array.
What you probably want to do is change
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:locations];
To something like
NSInteger someIndex = 0; //this will pick the first object in locations, e.g. #"Bottoms".
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:[locations objectAtIndex:someIndex]];
locations is an Array of Strings, so you need to pick one and not pass the entire Array.
Also, next time please dont just dump your code in here, but tell us which line caused the error. You are much more likely to get a quick response if you can point to the part that couses the problems.

Don't have the pictures from directory on CollectionView

I would want to show all the pictures in my directory however I am creating Folders in the Directory so that I can sort the pictures. I want to show all of the pictures in several folders. I am using the code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Bottoms"#"Top"#"Right"#"Left"#"Down"#"Up";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionTrash.delegate =self;
collectionTrash.dataSource=self;
for(NSString *str in directoryContent){
NSLog(#"i");
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
}}}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
NSLog(#"j");
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [allImagesArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseID = #"ReuseID";
TrashCell *mycell = (TrashCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseID forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[mycell viewWithTag:1];
imageInCell.image = [allImagesArray objectAtIndex:indexPath.row];
NSLog(#"a");
return mycell;
}
If you see my code you can notice that I have put NSLOG i and j. The j comes up but the i does not.... Is my way wrong showing all the pictures that are in several folders? I do not have any error.
If you have multiple folders then you need to iterate over the folders and then the folder contents to process all of it.
While this line:
NSString *location=#"Bottoms"#"Top"#"Right"#"Left"#"Down"#"Up";
Is technically legal, I guess you're thinking it will do some array / iteration thing for you. It won't. It just concatenates all of the strings together. You probably want something more like:
NSArray *locations = #[ #"Bottoms", #"Top", #"Right", #"Left", #"Down", #"Up" ];
Then you can run a loop over the folders and then the contents:
for(NSString *folder in locations) {
// get the folder contents
for(NSString *file in directoryContent) {
// load the image
}
}

Resources