Reputation: 4980
So I'm almost done with an app that is supposed to behave like a photo gallery. I'm running into a novice issue though trying to properly delete photos. So, I have 3 UIImageViews. The images are stored in an NSMutableArray and loaded from it on startup. They delete and save perfectly. But, if I were to delete the image in UIImageView #2, then close and relaunch the app, the image from UIImageView #3 slides into #2's spot. That's fine and everything, until I try and delete the image in #2's spot or anything above #2's.
I delete the photos based upon the name, so if I try and delete the photo in UIImageView #2, my code will search for Image2.png and delete it. But, now when I relaunch the app, UIImageView #3 is sitting in #2's spot, so when I try and delete UIImageView #3, it will not delete since its looking for Image2.png, which is no longer there. The file in its spot is named Image3.png. So, I'm somewhat at a loss and have no idea how to edit my code to get around this issue. Here is the current code that I'm working with, the culprit here is NSString *filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Image%i.png",view.tag]];
. (I've tagged each UIImageView and am deleting based upon that):
- (IBAction)deleteButtonPressed:(id)sender {
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:@"Delete"
message:@"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:@"No"
otherButtonTitles:@"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (UIImageView *)viewForTag:(NSInteger)tag {
UIImageView *found = nil;
for (UIImageView *view in self.array) {
if (tag == view.tag) {
found = view;
break;
}
}
return found;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
UIImageView *view = [self viewForTag:alertView.tag];
if (view) {
[self.array removeObject:view];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Image%i.png",view.tag]];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
[fileManager removeItemAtPath:filePath error:&error];
if (error)
NSLog(@"Error: %@",error);
}
((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
}
[self.user setObject:self.array forKey:@"images"];
}
And here is my full .m file just for reference: https://github.com/Joey502/Test-Thing/wiki/.m-Class-File
If anyone knows how to fix this issue that would be great!
Upvotes: 1
Views: 497
Reputation: 6039
What you want to do is create another NSMutableArray
, call it fileNamesArray
that stores the filenames associated with each (in the same order) UIImageView
s stored in your self.array
.
When launching the app, you should store each filename (NSString
s) in self.fileNamesArray
at the same time you add the UIImageView
s to self.array
. Then, in your delete function, when you remove the UIImageView
object from self.array
and delete it from the directory, you should also remove the filename from self.fileNamesArray
. So once the objects have been removed from both arrays, they will all shift by the same amount and each file name will correspond to the right image view.
Just to add to that: When deleting the images, you should use the tag
of the sender
to retrieve the filename from your self.fileNamesArray
which you would then use to delete the physical file, whereafter you would remove it from the array (along with the image view). Here's an example of what your delete function should be like:
if (view) {
[self.array removeObject:view]; //or you could do [self.array removeObjectAtIndex:alertView.tag];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:[self.fileNamesArray objectAtIndex:alertView.tag]];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
[fileManager removeItemAtPath:filePath error:&error];
if (error)
NSLog(@"Error: %@",error);
[self.fileNamesArray removeObjectAtIndex: alertView.tag];
}
Updated to address issues raised in comments:
In your applicationDidEnterBackground
method, you're adding all image views into self.array
again. What if the array isn't empty? Then you're just adding items that aren't needed. The only things you need in this method are the last two lines.
In your viewDidLoad
method, you're supposed to be adding the fileName
string to self.fileNamesArray
, but you've added the imageView
. Remove all the lines that add the image view to this array and after UIImage *loadedImage = [UIImage imageWithContentsOfFile:fullPath];
add this line [self.fileNamesArray addObject:fileName];
In your delete function, this line is missing two brackets: NSString *filePath = [documentsPath stringByAppendingPathComponent:[self.fileNamesArray objectAtIndex:alertView.tag;
. It should be NSString *filePath = [documentsPath stringByAppendingPathComponent:[self.fileNamesArray objectAtIndex:alertView.tag]];
. I'm wondering if this is why your whole directory is being deleted.
Don't forget that when you add images with the image picker, you should also add the filenames to the fileNamesArray
in your picker delegate method (in the correct order).
Upvotes: 3
Reputation: 506
Check your use of self.array. Sometimes you are using it to store/retrieve UIImageView's, other places you are storing/retrieving the images from the image views.
If you are trying to use self.array for two different purposes, then you either need to release and allocate a new one when switching purposes, or remove all the current contents before switching to the other purpose.
Upvotes: 1