Xcode-11-Beta (ios13)之前,使用以下代码为自定义搜索栏设置value for key值可以正常工作。现在会出现以下崩溃日志。
'NSGenericException',reason:'禁止访问UISearchBar的_searchField实例变量。这是应用程序错误'
- (UITextField *)textField
{
return [self valueForKey:@"_searchField"];
}
需要任何帮助。
Xcode-11-Beta (ios13)之前,使用以下代码为自定义搜索栏设置value for key值可以正常工作。现在会出现以下崩溃日志。
'NSGenericException',reason:'禁止访问UISearchBar的_searchField实例变量。这是应用程序错误'
- (UITextField *)textField
{
return [self valueForKey:@"_searchField"];
}
需要任何帮助。
UISearchBar.searchTextField
,因此您可以通过公共API简单地替换私有API实现。searchBar.searchTextField.backgroundColor = [UIColor blueColor];
if #available(iOS 13.0, *) {}
将其包装起来。在为iOS 13构建时,您将无法使用旧版本的Xcode。 - Jordan H如果我们想在使用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)
在UISearchBar
中,我们可以访问所有的textField属性并根据需要进行修改。
视图层次结构发生了变化。因此,通过打印(self.subviews[0]).subviews
,其中self
为UISearchBar
。
对于iOS 12及更早版本
对于iOS 13+
除了UISearchBarBackground
之外,现在我们还有UISearchBarSearchContainerView
和UISearchBarScopeContainerView
,而UISearchBarTextField
已经不存在了,被苹果提供的UISearchTextField
类中的扩展所代替。
extension UISearchBar {
open var searchTextField: UISearchTextField { get }
}
在iOS 13及以上的设备中,我们可以直接访问searchBar.searchTextField
,但是在iOS 12及以下的设备中访问该属性将导致应用程序崩溃。
崩溃信息如下:
[UISearchBar searchTextField]: unrecognized selector sent to instance
这是苹果官方文档
我也遇到了同样的崩溃问题,在IOS 13中,您不再需要使用.value(forKey:)方法。
这是导致崩溃的那一行代码:
if let searchField = searchController.searchBar.value(forKey: "_searchField") as? UITextField {
这就是解决方法:
let searchField = searchController.searchBar.searchTextField
请执行以下操作:
var searchTextField: UITextField?
if #available(iOS 13.0, *) {
searchTextField = searchBar.searchTextField
} else {
if let searchField = searchBar.value(forKey: "searchField") as? UITextField {
searchTextField = searchField
}
}
在 Swift 5 中,使用键值 "searchField" 而非带下划线的键值仍然可以正常工作。
guard let searchField = searchBar.value(forKey: "searchField") as? UITextField else { return }
if #available(iOS 13.0, *) { return value(forKey: "searchField") as? UITextField } else { return value(forKey: "_searchField") as? UITextField }
- GilroyKilroy 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
}
}
self.value(forKey: "searchField") as! UITextField
)。 - chocolate cake在尝试访问属性时,将所有的“_”下划线删除后,它适用于所有 iOS 版本。
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
}
}
let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton
- Jiffin
valueForKey:
去挖掘标准组件的私有子视图结构。这从来就不是有效的方法,而且它总是最终会出问题。使用提供的公共API完成你需要的功能。 - rmaddy