How to enumerate through UITextFields on iOS

2019-02-25 13:07发布

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 (UITextField *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?

3条回答
Ridiculous、
2楼-- · 2019-02-25 13:27

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.
    }
}
查看更多
Evening l夕情丶
3楼-- · 2019-02-25 13:40

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
    }
}
查看更多
Explosion°爆炸
4楼-- · 2019-02-25 13:48

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.

查看更多
登录 后发表回答