Question

I am accessing textfield of searchbar . This keeps changing

For iOS 6 i am using

    textField = [searchbar.subviews objectAtIndex:1];

It changed in iOS 7 there is a view and in that there was a subview from which we can get textField , So i am using following code for iOS 7 or greater iOS

    UIView *searchbarview = [searchbar.subviews objectAtIndex:0];
    NSLog(@"searchbarview.subviews Array is %@",searchbarview.subviews.description);
    textField = (UITextField *)[searchbarview.subviews objectAtIndex:1];

Now since iOS 7.1 the searchbarview has only one subview which is UISearchBarBackground unlike iOS 7.0 where it has two subviews, So i am not able to get textField even if i iterate through all the subviews using a for loop

Can anyone help me with this Thanks,

EDIT Here is the log of array returned by searchbarview.subviews , you can see it returns only 1 object which is UISearchBarBackground , so i am wondering where is UITextField object

searchbarview.subviews Array is (
"<UISearchBarBackground: 0xe6bc9d0; frame = (0 0; 768 50); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xe6bcb20>>"
)
Was it helpful?

Solution

I've tested on simulator of iOS 7.1. I see structure of UISearchBar like this:

===============================================

UISearchBar

++ UIView

++++ UISearchBarBackground

++++ UISearchBarTextField (This is UITextField object)

++++++++ _UISearchBarSearchFieldBackgroundView

++++++++ UIImageView

===============================================

take from Spark Inspector

So on iOS 7.1, you can get UITextField like this:

UIView *subviews = [searchbar.subviews lastObject];
UITextField *textView = (id)[subviews.subviews objectAtIndex:1];

===============================================

UPDATE

If your UISearchBar is in a UIViewController, try your code in method viewDidLoad or viewWillAppear!

Don't look for UITextField as soon as you create UISearchBar (look for after UISearchBar has already appeared on screen)

OTHER TIPS

I have created a recursive method which can work in any version of iOS

- (UITextField *) findTextFieldFromControl:(UIView *) view
{
    for (UIView *subview in view.subviews)
    {
        if ([subview isKindOfClass:[UITextField class]])
        {
            return (UITextField *)subview;
        }
        else if ([subview.subviews count] > 0)
        {
            UIView *view = [self findTextFieldFromControl:subview];
            if (view) {
                return (UITextField *)view;
            }
        }
    }
    return nil;
}

you can call this method

UITextField *searchBarTextField = [self findTextFieldFromControl:self.placeSearchBar];

You have to get the text field first.
Unfortunately the textfield is a private attribute.

You can loop and index the subviews to get the text field private attribute,
Or you can directly get the text field using the private attribute name.

Both way are same, you access the private attribute.

1. Loop

for subview in searchBar.subviews {
    for view in subview.subviews {
        if let searchField = view as? UITextField {
            // do something with the search field
        }
    } 
}

2. With key

let textField = searchBar.valueForKey("searchField") as? UITextField
let cancelBarButton = searchBar.valueForKey("cancelBarButtonItem") as? UIBarButtonItem

The proposed answers use private key -and will be rejected by Apple- or use an NSArrayand you cannot be sure this will persist in the future. If you want to change the color, attributes, etc of the text, use the appearanceWhenContainedIn:

    [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextAlignment:NSTextAlignmentCenter];

Use this code in order to get UITextField from UISearchBar:

    //First add the following macro:
    #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    //Then get the text field object:
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
    {
        for (id object in [[[yourSearchBar subviews] objectAtIndex:0] subviews])
        {
            if ([object isKindOfClass:[UITextField class]])
            {
                NSLog(@"text field found");
                UITextField *textField = (UITextField *)object;
                //do some actions
                break;
            }
        }
    }
    else
    {
        for (id object in [yourSearchBar subviews])
        {
            if ([object isKindOfClass:[UITextField class]])
            {
                NSLog(@"text field found");
                UITextField *textField = (UITextField *)object;
                //do some actions
                break;
            }
        }
    }

If you want to get the UITextField of the UISearchBar use the following line of code:

UITextField *textField = [searchBar valueForKey:@"_searchField"];

hope this help! =)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top