开发者

How to enumerate through UITextFields on iOS

Which is the correct way of enumerating through sub views to find text fields?

NSMutableArray *mutableTFs = [[NSMutableArray alloc] init];

for (UIView *view in [self.view subviews]) {
    if ([view isKindOfClass:[UITextField class]]) {            
        [mutableTFs addObject:view];
    }
}

OR

NSMutableArray *mutableTFs = [[NSMutableArray alloc] init];

for (UITe开发者_高级运维xtField *textField in [self.view subviews]) {
    [mutableTFs addObject:textField];
}

I know this isn't the correct wording, but what I don't understand is if it is the top method, how do you 'convert' it from a view to a text field?


Which is the correct way of enumerating through sub views to find text fields?

The first method is the correct one. The second method will iterate over all the subviews, not just the subviews with type UITextField. The type in the for() is only a hint to the compiler.

For more information, see this question.

how do you 'convert' it from a view to a text field?

This is what typecasting is for.

for (UIView *view in [self.view subviews]) {
    if ([view isKindOfClass:[UITextField class]]) {
        // you don't need to cast just to add to the array         
        [mutableTFs addObject:view];
        // typecasting works as it does in C
        UITextField *textField = (UITextField *)view;
        // do something with textField
    }
}


The first method is the only working method of the two.

The second method would add all subviews to the array. That is if you would change subViews to subviews.

You could do the following:

for (UITextField *textField in [self.view subviews]) {
    if ([textField isKindOfClass:[UITextField class]]) {            
        [mutableTFs addObject:textField];
    }
}

That way you wouldn't have to convert the view to a text field to do something text field specific instead of just adding it to an array.

EDIT: If you don't want to convert to a text field right away, maybe because you're looking for both text fields and text views. This is how you'd convert it later:

for (UIView *view in [self.view subviews]) {
    if ([view isKindOfClass:[UITextField class]]) {            
        UITextField *textField = (UITextField *)view;
        // Do whatever you want with the text field.
    }
    if ([view isKindOfClass:[UITextView class]]) {            
        UITextView *textView = (UITextView *)view;
        // Do whatever you want with the text view.
    }
}


Here's the best way.

// Make sure you're releasing this!
NSMutableArray *textFields = [[NSMutableArray alloc] init];

for (UITextField *textField in [self.view subviews]) {
    if ([textField isKindOfClass:[UITextField class]]) {
        [textFields addObject:textField];
    }
}

By specifying UITextField * as the type that you're performing the fast enumeration with, you'll be working with values that are casted already (by fast enumeration) from id to UITextField *. This does not guarantee that they are actually UITextFields though, so you still need a runtime check, in this case isKindOfClass:, to make sure the object you're currently working is really a UITextField.

So, both of them are correct, but only when combined.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜