0

I want to delete a UIButton from a UIScrollView without affecting the rest of the images.

The problem I am having is that one the first request the last image gets deleted (even if that is not the selected one) and then any subsequent requests result in nothing being deleted.

I started off by simply doing if(img == image) but that didn't produce a match. Then after reading this question I tried the second method (below) but that produces two different NSData results for the matching images.

Here is my code:

-(void) deleteImage:(UIButton*)button{ UIImage *image = [button imageForState:UIControlStateNormal]; NSLog(@"image %@", image); for (NSArray *imageArr in self.imageArray) { NSString *filename = imageArr[0]; UIImage *img = imageArr[1]; if([self image:img isEqualTo:image]){ RUN_ON_UI_THREAD(^{ [button removeFromSuperview]; }); double index = [self.imageArray indexOfObject:imageArr]; [self.imageArray removeObjectAtIndex:index]; } NSLog(@"img %@", img); } self.numberOfPhotosLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)[self.imageArray count]]; } - (BOOL)image:(UIImage *)image1 isEqualTo:(UIImage *)image2{ NSData *data1 = UIImagePNGRepresentation(image1); NSData *data2 = UIImagePNGRepresentation(image2); return [data1 isEqualToData:data2]; } 

deleteImage is called when the user holds down on a UIButton.

On viewDidLoad I look through the imageArray and use the following to add the UIButtons to the screen:

-(void) addImageToScreen:(UIImage*) image; { int adjustHeight = 0; int adjustWidth = 10; int imagesInARow = 7; int imageHeight = 75; int imageWidth = 75; int count = [self.imageArray count]; self.numberOfPhotosLabel.text = [NSString stringWithFormat:@"%i",count]; double index = 0; if (count > 0) { for (NSArray *imageArr in self.imageArray) { UIImage *img = imageArr[1]; if(image == img){ index = [self.imageArray indexOfObject:imageArr]; } } } if (count > 1 && count < imagesInARow) { adjustHeight = 0; adjustWidth = (20 * index) + (index * imageWidth); } UIButton* container = [[UIButton alloc] init ]; //create long press gesture recognizer(gestureHandler will be triggered after gesture is detected) UILongPressGestureRecognizer* longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; //adjust time interval(floating value CFTimeInterval in seconds) [longPressGesture setMinimumPressDuration:1.0]; //add gesture to view you want to listen for it(note that if you want whole view to "listen" for gestures you should add gesture to self.view instead) CGRect frame = CGRectMake(adjustWidth, 5, imageWidth, imageHeight); NSLog(@"self.imageArr %lu", (unsigned long)[self.imageArray indexOfObject:image]); [container setTag:[self.imageArray indexOfObject:image]]; [container setImage:image forState:UIControlStateNormal]; [container setFrame:frame]; [container addTarget:self action:@selector(displayFullScreenImage:) forControlEvents:UIControlEventTouchUpInside]; [container addGestureRecognizer:longPressGesture]; heldButton = container; [self.photosView addSubview:container]; [self.view addSubview:self.photosView]; } 

Here is how I populate imageArray:

-(void)buildImageArray{ [imageArray removeAllObjects]; NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSArray* dirs = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL]; [dirs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSString *filename = (NSString *)obj; NSString *extension = [[filename pathExtension] lowercaseString]; NSString *fileURL = [documentsDirectory stringByAppendingString: [@"/" stringByAppendingString:filename]]; NSString *pack_id = [NSString stringWithFormat: @"%ld", (long)self.dataObject.pack_id]; NSNumber *newNID = NID; if([NID integerValue] == -1 && [dict1 count] > 0){ int noteID = [[dict1 valueForKey:@"noteID"] integerValue]; newNID = [NSNumber numberWithInt: noteID - 1]; }else if([NID integerValue] == -1){ newNID = [NSNumber numberWithInt:[NID integerValue] - 1]; } NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; //self.signedInSwitch.on = true; NSString *username = [prefs objectForKey:@"username"]; NSString *matchFileName = [NSString stringWithFormat:@"%@_%@_%@_notes_image", username, pack_id, newNID]; if ([fileURL containsString:matchFileName]) { NSLog(@"filename %@", filename); UIImage *image = [UIImage imageWithContentsOfFile:fileURL]; if(image != nil){ NSMutableArray *subArray = [[NSMutableArray alloc] init]; [subArray addObject:filename]; [subArray addObject:image]; [imageArray addObject:subArray]; } } }]; } 

Here is the response I get from comparing the images:

 Selected Image <UIImage: 0x17428e5b0> size {4032, 3024} orientation 0 scale 1.000000 2016-12-02 13:26:38.517130 eCoss[2806:1722107] Array Image 0 <UIImage: 0x17428e970> size {4032, 3024} orientation 0 scale 1.000000 2016-12-02 13:26:39.357693 eCoss[2806:1722107] Selected Image <UIImage: 0x17428e790> size {4032, 3024} orientation 0 scale 1.000000 2016-12-02 13:26:39.357819 eCoss[2806:1722107] Array Image 1 <UIImage: 0x17428e970> size {4032, 3024} orientation 0 scale 1.000000 2016-12-02 13:26:40.318356 eCoss[2806:1722107] Selected Image <UIImage: 0x17428e970> size {4032, 3024} orientation 0 scale 1.000000 2016-12-02 13:26:40.318485 eCoss[2806:1722107] Array Image 2 <UIImage: 0x17428e970> size {4032, 3024} orientation 0 scale 1.000000 
12
  • So what do you want exactly? Is it not working ? or you need to call deleteImage function after hand is removed from the button ? Commented Dec 2, 2016 at 13:02
  • @Venkat Ultimately I want to remove the selected Image but in order to do that I need see if image (the selected one) matches one of the images in the imageArray Commented Dec 2, 2016 at 13:04
  • so the above condition is failing? Commented Dec 2, 2016 at 13:07
  • @Venkat yes, the if([self image:img isEqualTo:image]){ never produces a match when it should Commented Dec 2, 2016 at 13:09
  • just to confirm, how you are setting image for button? can you post the code for that? also pls show me the code for how you are adding image into array Commented Dec 2, 2016 at 13:10

3 Answers 3

1

For this functionality, comparing image data uses excessive amount of processor. Instead, you can set button.tag = [image_index] while populating your scrollview.

Than, in your action, you can use button.tag to identify which image is clicked.

- (void)deleteImage:(UIButton*)button { int clickedImageIndex = button.tag; ... [self.imageArray removeObjectAtIndex:clickedImageIndex]; ... } 
Sign up to request clarification or add additional context in comments.

Comments

0

One way is to convert them to image data first, and then compare that.

- (BOOL)image:(UIImage *)image1 isEqualTo:(UIImage *)image2 { NSData *data1 = UIImagePNGRepresentation(image1); NSData *data2 = UIImagePNGRepresentation(image2); return [data1 isEqual:data2]; } 

OR

- (BOOL)image:(UIImage *)aImage1 equalsTo:(UIImage *)aImage2 { NSData *img1Data = UIImageJPEGRepresentation(aImage1, 1.0); NSData *img2Data = UIImageJPEGRepresentation(aImage1, 1.0); return [img1Data isEqualToData:img2Data]; } 

A Swift implementation of @Simon's answer:

func image(image1: UIImage, isEqualTo image2: UIImage) -> Bool { let data1: NSData = UIImagePNGRepresentation(image1)! let data2: NSData = UIImagePNGRepresentation(image2)! return data1.isEqual(data2) } 

Or by extending UIImage based on @nhgrif's suggestion:

import UIKit extension UIImage { func isEqualToImage(image: UIImage) -> Bool { let data1: NSData = UIImagePNGRepresentation(self)! let data2: NSData = UIImagePNGRepresentation(image)! return data1.isEqual(data2) } } 

Comments

0

Use this sample code:

#import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIButton *imageButton; @property (strong, nonatomic) NSMutableArray *imageArray; @property (strong, nonatomic) NSMutableArray *imageButtons; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.imageArray = [[NSMutableArray alloc]initWithCapacity:0]; self.imageArray = [NSMutableArray arrayWithObjects:[UIImage imageNamed:@"bird.jpeg"],[UIImage imageNamed:@"panda.jpg"],[UIImage imageNamed:@"elephant.jpg"],[UIImage imageNamed:@"parrot.jpeg"],[UIImage imageNamed:@"kid.jpg"], nil]; //Create five buttons and add to viewController for(int i=0; i<self.imageArray.count; i++) { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(20, 100 + i * 110, 100, 100); [button setImage:self.imageArray[i] forState:UIControlStateNormal]; button.tag = i; [button addTarget:self action:@selector(deleteImageForButton:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; [self.imageButtons addObject:button]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (BOOL)image:(UIImage *)image1 isEqualTo:(UIImage *)image2{ NSData *data1 = UIImagePNGRepresentation(image1); NSData *data2 = UIImagePNGRepresentation(image2); return [data1 isEqualToData:data2]; } - (void)deleteImageForButton:(UIButton *)button{ UIImage *image = [button imageForState:UIControlStateNormal]; for (UIImage *presentImage in self.imageArray){ if([self image:presentImage isEqualTo:image]){ [button removeFromSuperview]; double index = [self.imageArray indexOfObject:presentImage]; [self.imageArray removeObjectAtIndex:index]; break; } } } 

Without image comparison, we can do like this(using button tags as index):

- (void)deleteImageForButton:(UIButton *)button{ [self.imageArray removeObjectAtIndex:button.tag]; [button removeFromSuperview]; for(long i=button.tag + 1; i<= self.imageArray.count ; i++) { UIButton *button = (UIButton *)[self.view viewWithTag:i]; button.tag = button.tag - 1; [button setImage:self.imageArray[button.tag] forState:UIControlStateNormal]; } } 

Note: Replace image names with your own images.

3 Comments

Thanks for the response, this still deleted the last image in the array after selecting the first
@jampez77 can you please post a screenshot before and after deletion?
@jampez77 please check my code and reply. If necessary i will add my sample project to test..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.