I am looking for a way to automatically localize texts on buttons/textfields etc and for this method I need to find all (for example) UIButton's on a UIView.
I tried the following 2 methods, but they both do no work like I want them to work:
for (UIView* subView in self.view.subviews)
{
NSLog(@"object class : %@", [subView class]);
if ([subView isMemberOfClass:[UIButton class]])
NSLog(@"Button found!");
}
The problem with this piece of code is that a RoundedRectButton does not match the UIButton class, while it really is just a UIButton.
I also tried the following:
for (UIButton* button in self.view.subviews)
{
// Do my stuff
}
But the stupid thing is, is that cocoa-touch actually just lists all subviews in that for-loop (also the UITextFields etc).
Is there a way to actually just get all UIButtons from a view? Or do I really need to find controls by looking at their selectors.
Why write one-off code like this when you can dial up the awesomeness by adding a category method to UIView
using blocks? Take a look at the code at the very bottom. Using this recursive method with blocks you can do things like disable all UITextFields in a view controller's view:
[self.view forEachUITextFieldDoBlock:^(UITextField *textField) {
textfield.enabled = NO;
}];
Or fade out all UITextFields in a view controller's view:
[UIView animateWithDuration:0.25 animations:^{
[self.view forEachUITextFieldDoBlock:^(UITextField *textField) {
textField.alpha = 0.0;
}];
}
completion:^(BOOL finished){
// nothing to do for now
}];
Blocks are pretty amazing in that you can even pass other methods inside a block. For example, the code below passes each UITextField
found to my inserAdornmentImage:forTextView
method, which adds a custom background image to each text view:
[self.view forEachUITextFieldDoBlock:^(UITextField *textField) {
[self insertAdornmentImage:textFieldBGImage forTextField:textField];
}];
Blocks make the method incredibly flexible so you aren't having to write a specialized method each time you want to do something new with the controls you find. Here's the magic sauce:
@implementation UIView (Helper)
- (void) forEachUITextFieldDoBlock:(void (^)(UITextField *textField))block
{
for (UIView *subview in self.subviews)
{
if ([subview isKindOfClass:[UITextField class]])
{
block((UITextField *)subview);
} else {
[subview forEachUITextFieldDoBlock:block];
}
}
}
@end
the first method is correct, except you need to change isMemberOfClass function to isKindOfClass:
isKindOfClass: Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With