NSMutableArray remove object 1 before last object - objective-c

I have many UIImageView in an NSMuatableArray and I need to remove a certain UIImageView from the view, but I think that if I release the UIImageView it will still be in the array.
I don't want that, but there is a little problem. The UIImageView that I need to remove is exactly 1 object before the last object in the array, so I can't use removeLastObject. I do know the tag number, but I can't write it like this because I would change the array while using it.
for (UIImageView *k in array1) {
if (k.tag==tagzahl-1) {
if (x==1){
[k removeFromSuperview];
[array1 remove object:k];
}
}
}
I am using: [array1 addObject:myimage]; to add the UIImageViews to the array, so I do not know the index.

If you know that tag which you say you do then
UIView *view = [viewContainingImageView viewWithTag:tagzahl-1];
[view removeFromSuperview];
[array1 removeObject:view];

if ([array1 count] >= 2)
{
NSUInteger index = [array1 count] - 2;
UIImageView *view = [array1 objectAtIndex:index];
[array1 removeObjectAtIndex:index];
[view removeFromSuperview];
}

Related

UIImageView Disappear after remove image

I tried to remove my images one by one; for that it's ok but when I tried to add a new image by my library nothing appear, I think my code removes my UIImageView.
-(IBAction)remove:(id)sender {
for (NSUInteger i = 0; i < [self.imageArray count]; i--) {
UIImageView *view = self.imageArray[i];
for (view in [self.view.subviews reverseObjectEnumerator])
if ([view isKindOfClass:[UIImageView class]]){
[view removeFromSuperview];
break;
}
}
}
If you are simply trying to remove and add UIImageViews from a mutable array, you can use the following the code.
//Create and add items to mutable array
NSMutableArray *arr = [#[] mutableCopy];
[arr addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myImage1"]]];
[arr addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myImage2"]]];
[arr addObject:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myImage3"]]];
//Create temp array to to hold items to remove
NSMutableArray *arrWithItemsToRemove = [#[] mutableCopy];
for(UIView *view in arr)
if([view isKindOfClass:[UIImageView class]])
[arrWithItemsToRemove addObject:view];
//Remove objects
[arr removeObjectsInArray:arrWithItemsToRemove];
NSLog(#"%#", arr);
There are problems with the code you are showing. I am not sure why you have two for loops, and self.imageArray[i] is not even valid Objective-C.
So I am going to assume that you have a view (self.view) which contains subviews, some of which are UIImageViews, and that these are the views you wish to remove.
I would do it like this:
NSMutableArray* viewsToDelete = [NSMutableArray new];
for(UIView* view in self.view.subViews) {
if([view isKindOfClass:[UIImageView class]){
[viewsTodDelete addObject:view];
}
}
// Now remove these
for(UIImageView* imageView in viewsToDelete){
[imageView removeFromSuperView];
}
Note that [subview removeFromSuperview] will delete the subview from its parents subviews array, and that is a potential source of problems.
I am not sure if my code will solve your original problem, but this code is cleaner and simpler than the code you showed us, so it is a good place to start.

Get labels in current view

I have a need to get all labels in current view. is it possible? If yes, please advise how can i realize this?
For example, i need to collect all labels from startup screen, then from currently showing popup and etc.
Thanks!
Here is the way to go----
NSMutableArray *labels = [NSMutableArray array];
for (UIView *v in someSuperview.subviews) {
if ([v isKindOfClass:[UILabel class]]) {
[labels addObject:v];
}
}
Suppose if you want to collect label in an array, you can try this:
for (UIView *subview in self.view.subviews)
{
if(subview isKindOfClass:[UILabel class])
{
[arrayOfLabels addObject:subview];
}
}
If you want it to do by means of accessibilityLabel, here are the steps to get view from given accessibilityLabel. Method viewContainingAccessibilityElement:element is extension method to UIAccessibilityElement class.
UIAccessibilityElement *element = [[UIApplication sharedApplication] accessibilityElementWithLabel:label];
UIView *view = (UIView*)[UIAccessibilityElement viewContainingAccessibilityElement:element];
Let me know if it works

Issue with tags in Xcode

I have an app that displays 9 UIImageViews, and I'm adding in the ability for the user to delete them. The code works fine, except I'm having some issues with using tags in interface builder. It seems that my code deletes the image in the ImageView based upon its position in the array. So, if I have 3 UIImageViews, I will set the first UIImageViews tag to 1, the second image view's tag to 2, and the third to 3. I try to delete the third one first, and I get the error:
Terminating app due to uncaught exception NSRangeException, reason: *' -[__NSArrayM removeObjectAtIndex:]: index 3 beyond bounds [0 .. 1]'
This is the code that I'm using:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", 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;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes. Deleting index %d of %d", alertView.tag, [array count]);
NSLog(#"The tag is %i", alertView.tag);
[self.array removeObjectAtIndex: alertView.tag];
NSLog(#"After deleting item, array count = %d", [array count]);
NSLog(#"Returned view is :%#, in view: %#", [self.view viewWithTag:alertView.tag], self.view);
((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
}
[self.user setObject:self.array forKey:#"images"];
}
I have to put the first image in the 0 index of the array, but I know that you can't have a tag of 0 since it is the default tag. So, I have no idea how to get around this issue. Any help is much appreciated, thanks!
I don't think static tags as index numbers will work for this because, even if you get it right for the first delete, the match-up of tags and array offsets will change if you delete something that's not the last array element.
You'd be better to write a method to step through the array and return the item with a tag that matches. Or, if you want direct access via a tag, use a dictionary and build the keys using the tags.
Code for tag matching would look something like:
- (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 {
// ...
// Replacing: [self.array removeObjectAtIndex: alertView.tag];
UIImageView *view = [self viewForTag:alertView.tag];
if (view) {
[self.array removeObject:view];
}
// ...
}

UIImageView added to an NSArray doesn't respond

I am fairly new to Objective-C, this is the first time I really don't know what to do.
I have a class - Parser - which creates UIImageViews, inits them with images and adds them to the UIView. The class also adds these UIImageViews to NSMutableArray - imgArray, which is a property of another class - Page.
Then, on the click of a button, I call the Page class from a Manager class, loop through the imgArray and try to set a new images for the UIImageViews in the array.
It doesn't work. Actually nothing I do to the UIImageViews doesn't work.
I try [img removeFromSuperView], [img setHidden:YES] and more. It doesn't response.
Here I declare the Array property in Page:
#property (nonatomic, retain) NSMutableArray *imgArray;
Here is the code from Parser where I create the image and add it to the array:
UIImageView *img = [[UIImageView alloc] initWithFrame: frame];
NSString *name = [c imageSource];
[img setImage: [UIImage imageFromBook: name]];
[view addSubview: img];
[c setImage:img];
if (!page.imgArray)
{
page.imgArray = [[NSMutableArray alloc] init];
}
[page.imgArray addObject:img];
[img release];
Here is the loop code from the Manager:
- (void) set3D:(bool)is3D
{
Page *page = [[DataManager data] currentPage];
int count = [page.imgArray count];
for (int i = 0; i < count; i++)
{
UIImageView *img = [page.imgArray objectAtIndex:i];
[img setImage:[UIImage imageNamed:image3DSource]];
}
}
Thanks in advance for any help!
There is no need to store the UIImageView's in an array.
When the UIImageView's are created, you can tag them with an arbitrary number, like.
#define K_MIN_IMGV 100
#define K_MAX_IMGV 120
- (void) setupViews
{
for (NSInteger count = K_MIN_IMGV; count < K_MAX_IMGV; ++count)
{
UIImageView *imgV = // create image view, set properties
imgV.tag = count; // tag the views for easy retrieval later
...
[mainView addSubview: imgV]; // add subviews
[imgV release], imgV = nil; // mainView now manages, release our allocation
}
}
// how to set new images
- (void) setupNewImages
{
for (NSInteger count = K_MIN_IMGV; count < K_MAX_IMGV; ++count)
{
UIImageView *imgV = (UIImageView *) [mainView viewWithTag: count]; // retrieve imageView
[imgV setImage: newImage]; // set new image
}
}
// To remove the imageView, you can use
UIImageView *imgV = (UIImageView *) [mainView viewWithTag: 123];
[imgV removeFromSuperview];
Have you tried to enumerate through the array using:
for(UIImageView* imageView in page.imgArray)
{
//Do code
}
This will tell you if there any imageViews in page.imgArray.
How are you adding objects to NSMutableArray and how are you initialising your NSMutableArray.
I remember having a problem adding objects to NSMutableArray but setting my init to solved this:
NSMutableArray* mutableArray = [NSMutableArray array];
Also what properties have you set on imgArray in page? Are you retaining the values?
Need to see more code to gain a fuller understanding.

NSArray remove last object of type?

Working with an array of UIViews and UIImageViews ([[[UIApplication sharedApplication] window] subviews]). I need to remove only the object of the highest index of the UIImageView type.
You can use indexOfObjectWithOptions:passingTest: method to search the array in reverse for an object that passes a test using a block, and then delete the object at the resulting position:
NSUInteger pos = [myArray indexOfObjectWithOptions:NSEnumerationReverse
passingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [obj isKindOfClass:[UIImageView class]]; // <<== EDIT (Thanks, Nick Lockwood!)
}];
if (pos != NSNotFound) {
[myArray removeObjectAtIndex:pos];
}
another block-based solution
[window.subviews enumerateObjectsWithOptions:NSEnumerationReverse
usingBlock:^(id view, NSUInteger idx, BOOL *stop)
{
if ([view isKindOfClass:[UIImageView class]]){
[view removeFromSuperview];
*stop=YES;
}
}];
non-block solution:
for (UIView *view in [window.subview reverseObjectEnumerator])
{
if ([view isKindOfClass:[UIImageView class]]){
[view removeFromSuperview];
break;
}
}
I published some demo code, that shows both solutions.
How about:
UIWindow *window = [[UIApplication sharedApplication] window];
UIView *imageView = nil;
for (UIView *view in window.subviews)
{
if ([view isKindOfClass:[UIImageView class]])
{
imageView = view;
}
}
//this will be the last imageView we found
[imageView removeFromSuperview];