Henry F
Henry F

Reputation: 4980

Deleting the appropriate image

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

Answers (2)

sooper
sooper

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) UIImageViews stored in your self.array.

When launching the app, you should store each filename (NSStrings) in self.fileNamesArray at the same time you add the UIImageViews 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:

  1. 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.

  2. 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];

  3. 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.

  4. 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

Uilleann
Uilleann

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

Related Questions