views:

734

answers:

2

i'm programmatically adding a couple UIButtons to my view. After clicking one of the buttons they all should be 'removeFromSuperView' or released, not just one.

for (int p=0; p<[array count]; p++) {  
    button = [[UIButton alloc] initWithFrame:CGRectMake(100,100,44,44)];  
    button.tag = p;  
    [button setBackgroundImage:[UIImage imageNamed:@"image.png"]   forState:UIControlStateNormal];    
    [self.view addSubview:button];    
    [button addTarget:self action:@selector(action:)   forControlEvents:UIControlEventTouchUpInside];  
}

Now this is the part where all buttons should be removed. Not just one.

-(void) action:(id)sender{  
    UIButton *button = (UIButton *)sender;  
    int pressed = button.tag;  
    [button removeFromSuperview];  
}

I hope someone can help me with this one!

A: 
NSMutableArray *buttonsToRemove = [NSMutableArray array];
for (UIView *subview in self.view.subviews) {
    if ([subview isKindOfClass:[UIButton class]]) {
        [buttonsToRemove addObject:subview];
    }
}
[buttonsToRemove makeObjectsPerformSelector:@selector(removeFromSuperview)];

EDIT:
I have edited my answer to a better solution.
Now the objects are not removed from the array while enumerating it...

Michael Kessler
it should read "for (UIView *subview in self.view.subviews)" I guess
Felix
Thnx Micheal! After changing (UIView *subview in self.view) in: (UIView *subview in [self.view subviews]) it works like a charm!
Martijn
@Felix, thank you for the correction. You are absolutely right. I've edited my answer.
Michael Kessler
I downvoted this answer because it is bad advice. Apple clearly states that while using Fast Enumeration you should *not* modify the collection's contents. See http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocFastEnumeration.html#//apple_ref/doc/uid/TP30001163-CH18-SW1
St3fan
+4  A: 

A more efficient way would be to add each button to an array when you create it, and then when a button is pressed, have all the buttons in the array call the -removeFromSuperView method like this:

[arrayOfButtons makeObjectsPerformSelector:@selector(removeFromSuperView)];

Then after that, you can either keep the buttons in the array and reuse them, or call removeAllObjects to have them released. Then you can start populating it again later.

This saves you from having to walk through the entire view hierarchy looking for buttons.

Jasarien
Good solution...
Michael Kessler
really clean idea. i did that always, with an extra view and then performing this "makeObjectsPerformSelector:" to that view. but doing this with an array is much better.
choise