UItextField within UISearchbar failing after iOS 7

2020-02-11 11:04发布

问题:

I have a UITextField for the UISearchBar which this was working until iOS 7 upgrade and now it fails at this line: UITextField *textfield=(UITextField*)[[searchBar subviews] objectAtIndex:1];

any idea how to fix this? thanks

    // search bar
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 190.0, 44.0)];
searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
UIView *searchBarView = [[UIView alloc] initWithFrame:CGRectMake(90.0, 0.0, 230.0, 44.0)];
searchBarView.autoresizingMask = 0;
searchBar.delegate = self;

searchBar.layer.borderColor=[UIColor whiteColor].CGColor;

UITextField *textfield=(UITextField*)[[searchBar subviews] objectAtIndex:1];

[searchBarView addSubview:searchBar];

self.navigationItem.titleView = searchBarView;

回答1:

try this , it's work in Both IOS6 and IOS7+ and safe approch

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setFont:[UIFont fontWithName:@"ArialMT" size:10]];


回答2:

It's not a good idea to assume that second searchBar's subview will be UITextField.

I printed out subviews for UISearchBar, that's what I got on iOS 7:

<__NSArrayM 0x17d141f0>(
<UIView: 0x17d34f40; frame = (0 0; 320 44); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x17d34fa0>>
)

Only one subview, so your ... objectAtIndex:1] will definitely crash.

You can use the following category for UIView to find UITextField in your searchBar:

@interface UIView(Utils)

-(UIView*)findSubviewRecursivelyOfClass:(Class)subviewClass;

@end

@implementation UIView(Utils)

-(UIView*)findSubviewRecursivelyOfClass:(Class)subviewClass
{
  if( [self isKindOfClass:subviewClass] ) {
    return self;
  } else {
    for( UIView* child in self.subviews ) {
      UIView* result = [child findSubviewRecursivelyOfClass:subviewClass];
      if( result ) {
        return result;
      }
    }
    return nil;
  }
}

@end


回答3:

Try this one for iOS7.

TESTED

for (id object in [searchBar subviews])
    {
        for (id subObject in [object subviews])
        {
            if ([subObject isKindOfClass:[UITextField class]])
            {
                UITextField *textfield=(UITextField*)subObject;
            }
        }
    }

iOS6

for (id object in [searchBar subviews]) {
        if ([object isKindOfClass:[UITextField class]]) {
            UITextField *textfield=(UITextField*)object;
        }
    }


回答4:

How about a recursive method that can trick to work in any version

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


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