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.
Related
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
I am having a UIView that has button in it. The buttons are not in some array.
I would like to look at the whole UIView (using for loop) and look for a button by its title, and later remove it.
- (void)removeButtonByTitle:(NSString*)name
{
for (buttons in view) {
// find the button with the name "name" and remove it from the view
}
}
I couldn't find a way to do that without saving their names/pointers to an array.
It's generally preferable to use the tag property for this. Then you can simply find the button with the viewWithTag: method and don't have to adjust your code if you decide to change the button title or localize your app.
If you really need to find a button by its title, you could do it like this:
NSString *buttonTitle = #"name";
UIButton *buttonWithTitle = nil;
for (UIButton *button in view.subviews) {
if (![button isKindOfClass:[UIButton class]]) continue;
if ([[button currentTitle] isEqualToString:buttonTitle]) {
buttonWithTitle = button;
break;
}
}
//do something with the button...
Well you could do it like this:
for (UIView *v in view.subviews)
if ([v isKindOfClass:[UIButton class]] && [[(UIButton *)v currentTitle] isEqualToString:#""])
//remove
But I must say that doesn't sound like a robust solution, your button title could change during localization or it may be different for different states.
Do that:
- (void)removeButtonByTitle:(NSString *)name
{
for (UIView *tempView in self.subviews)
{
if ([tempView isKindOfClass:[UIButton class]]) // make sure it's actually a UIButton
{
UIButton *button = tempView;
if ([button.titleLabel.text isEqualToString:name]) // compare the title
{
[button removeFromSuperview];
}
}
}
}
Check this:
-(void)removeButtonWithTitle:(NSString*)titleString {
NSArray *subViews = [self.view subviews];
[subViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if([obj isKindOfClass:[UIView class]]) {
NSArray *subViewsArray = [(UIView*)obj subviews];
for (int i=0; i<[subViewsArray count]; i++) {
id subViewObj = [subViewsArray objectAtIndex:i];
if([subViewObj isKindOfClass:[UIButton class]] && [[(UIButton*)subViewObj titleLabel].text isEqualToString:titleString]) {
[subViewObj removeFromSuperview];
*stop = YES;
break;
}
}
}
}];
}
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];
}
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.
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];