44

在 Xcode-11-Beta (ios13) 之前,下面的代码用于自定义搜索栏值的键以使 textField 正常工作。现在低于崩溃日志。

'NSGenericException',原因:'禁止访问 UISearchBar 的 _searchField ivar。这是一个应用程序错误'

- (UITextField *)textField
{
 return [self valueForKey:@"_searchField"];
}

任何帮助表示赞赏。

4

12 回答 12

73

SDK 现在提供UISearchBar.searchTextField,因此您可以简单地将私有 API 实现替换为公共 API。

searchBar.searchTextField.backgroundColor = [UIColor blueColor];
于 2019-06-21T00:15:12.257 回答
22

我遇到了同样的崩溃,使用 IOS 13 你不再需要 .value(forKey:)

这是导致崩溃的行:

if let searchField = searchController.searchBar.value(forKey: "_searchField") as? UITextField {

这是修复:

let searchField = searchController.searchBar.searchTextField
于 2019-07-30T10:44:05.407 回答
22

如果我们想在使用 Xcode 11 编译时也支持 iOS 12 及更早版本,那么我们可以扩展UISearchBar我们可以获取文本字段的位置

extension UISearchBar {

    var textField : UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        } else { // Fallback on earlier versions
            for subview in subviews.first?.subviews ?? [] {
                if let textField = subview as? UITextField {
                    return textField
                }
            }
        }
        return nil
    }
}

用法

searchBar.textField?.font = UIFont.systemFont(ofSize: 15.0)

在这里,我们可以访问所有 textField 的属性并根据我们的需要进行修改UISearchBar

视图层次结构发生了变化。所以通过打印self.subviews[0]).subviewswhere selfinUISearchBar


适用于iOS 12及更早版本

在此处输入图像描述

对于iOS 13+

在此处输入图像描述

除了UISearchBarBackground,现在我们还有UISearchBarSearchContainerViewand UISearchBarScopeContainerViewwhileUISearchBarTextField丢失了,它被 Apple 在UISearchTextField课堂上提供的扩展所取代

extension UISearchBar {

    
    open var searchTextField: UISearchTextField { get }
}

所以我们可以在 iOS 13 及以上的设备中直接访问searchBar.searchTextField,而如果我们在 iOS 12 及以下的 OS 设备中尝试访问该属性会导致崩溃。

崩溃将是这样的:

[UISearchBar searchTextField]:发送到实例的无法识别的选择器

在此处输入图像描述

这是苹果文档

于 2019-09-23T06:26:54.937 回答
9

做这个:

 var searchTextField: UITextField?
    if #available(iOS 13.0, *) {
        searchTextField = searchBar.searchTextField
    } else {
        if let searchField = searchBar.value(forKey: "searchField") as? UITextField {
            searchTextField = searchField
        }
    }

这将根据版本检查为您提供适当的搜索栏文本字段。

于 2020-03-26T08:21:19.287 回答
7

它仍然适用于我没有下划线的关键“searchField”。斯威夫特 5

guard let searchField = searchBar.value(forKey: "searchField") as? UITextField else { return }
于 2019-10-01T09:47:30.433 回答
4

如果你想检查 iOS 版本!

 if #available(iOS 13.0, *) {
    searchBar.searchTextField.clearButtonMode = .never
 } else {
    searchBar.textField.clearButtonMode = .never
 }

不要忘记扩展名:

extension UISearchBar {

 var textField : UITextField{
    return self.value(forKey: "_searchField") as! UITextField
 }
}
于 2019-09-27T01:10:22.567 回答
3

到处都删除了“_”下划线(在尝试访问属性时),它适用于所有 iOS 版本。

于 2019-11-07T06:42:21.923 回答
2
extension UISearchBar {

    var textField : UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        } else {
            // Fallback on earlier versions
            return value(forKey: "_searchField") as? UITextField
        }
        return nil
    }
}
于 2019-09-30T14:37:11.680 回答
0

对于 iOS 11 及更早版本,您可以像这样进行检查:

if #available(iOS 11, *){
            self.searchBar.placeholder = "Search by Name"
            self.searchBar.setSerchFont(textFont: UIFont(name:AppFontLato.Regular, size:14.0 * DeviceInfo.aspectRatio()))
            self.searchBar.setSerchTextcolor(color: Colors.black51)
        }
        else{
            if let searchTextField = self.searchBar.value(forKey: "_searchField") as? UITextField, let clearButton = searchTextField.value(forKey: "_clearButton") as? UIButton {
                searchTextField.placeholder = "Search by Name"
                searchTextField.font = UIFont(name:AppFontLato.Regular, size:14.0 * DeviceInfo.aspectRatio())
                searchTextField.textColor = Colors.black51
            }
        }

希望这可以帮助

于 2019-10-09T11:58:58.947 回答
0

我在取消按钮值 forkey 上崩溃了。是否可以在 iOS 13 中自定义取消按钮。在此处输入图像描述

于 2019-11-12T17:00:51.123 回答
0

您可以使用这个答案,在 iOS 13 中运行良好:-

https://stackoverflow.com/a/60503506/9863222

于 2020-03-03T09:05:07.500 回答
0
if #available(iOS 13.0, *) {
        self.searchBar.searchTextField.clearButtonMode = .never
    } else {
        // Fallback on earlier versions
        if let searchField = searchBar.value(forKey: "searchField") as? UITextField {
            searchField.clearButtonMode = .never
        }
    }
于 2020-12-11T08:43:31.377 回答