Filippo
Filippo

Reputation: 1046

iOS 13 Custom UISearchBar _searchField crash

with the new iOS 13, i got a crash trying to change the UISearchBar textField properties using valueForKey:@"_searchField"

Now seems that Apple has changed something.

I've created a subclass of UIView with the following custom method and now it seems to work!

- (UIView *)findSubview:(NSString *)name resursion:(BOOL)resursion
{
    Class class = NSClassFromString(name);
    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:class]) {
            return subview;
        }
    }

    if (resursion) {
        for (UIView *subview in self.subviews) {
            UIView *tempView = [subview findSubview:name resursion:resursion];
            if (tempView) {
                return tempView;
            }
        }
    }

    return nil;
} 

You can simply call this method this way to change UITextField properties:

UITextField *textField = (UITextField*)[self findSubview:@"UITextField" resursion:YES];

Obviously this is an Objective-c snippet and if anyone knows how to write the same code in swift can add it to the answers.

Happy coding!

Upvotes: 3

Views: 5145

Answers (3)

guru
guru

Reputation: 2817

My project is in Objective c and i need to support XCode10 as well so, After two days of headache below line saved my day :

txfSearchField = [_searchBar valueForKey:@"searchField"];

Just need to Remove _ from the old code!!!

In Swift also you can use the same.

Hope it will help someone!

Upvotes: 1

Luke Redmore
Luke Redmore

Reputation: 449

I'm not sure if it would help, but UISearchBar has a new searchTextField property allowing you to access its UISearchTextField and, in turn, its UITextField:

let searchBar = UISearchBar()
var searchField : UITextField
if #available(iOS 13.0, *) {
    searchField = searchBar.searchTextField
} else {
    searchField = //Your original method
}

Upvotes: 10

Hitesh Surani
Hitesh Surani

Reputation: 13557

You can do it by using below extension

extension UISearchBar {

    func getAllSubview<T : UIView>(type : T.Type) -> [T]{
        var all = [T]()
        func getSubview(view: UIView) {
            if let aView = view as? T{
                all.append(aView)
            }
            guard view.subviews.count>0 else { return }
            view.subviews.forEach{ getSubview(view: $0) }
        }
        getSubview(view: self)
        return all
    }
}

Use like:

self.searchBar.getAllSubview(type: UITextField.self).first

Output:

<UISearchBarTextField: 0x7fc68d850a00; frame = (0 0; 0 0); text = ''; opaque = NO; layer = <CALayer: 0x600000d29aa0>>

Upvotes: 2

Related Questions