用 UIActivityViewController 替换 UISearchBar 放大图标
Replacing UISearchBar magnifying icon with UIActivityViewController
我搜索了一整天,但找不到此代码的修复程序。
此扩展将 UISearchField 放大图标替换为 UIActivityView(为真时显示加载图标)
扩展在 iOS 12、Xcode 10.3 上运行良好,但在我更改之后进入 iOS 13, Xcode 11 Beta 4 它停止工作了。
我仍然使用这个做了一个解决方法:
if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField {
let loadingIcon = UIActivityIndicatorView()
loadingIcon.style = .medium
loadingIcon.backgroundColor = UIColor.clear
loadingIcon.startAnimating()
textFieldInsideSearchBar.leftView = loadingIcon
}
但我不明白扩展停止工作的原因。
我还注意到 .flatMap
在 iOS 13 中被 弃用并改为 .compactMap
但是作为我知道没有区别,我已经尝试将 .flatMap
更改为 .compactMap
但仍然没有用。
这是分机:
extension UISearchBar {
private var textField: UITextField? {
let subViews = self.subviews.compactMap { [=11=].subviews }
return (subViews.filter { [=11=] is UITextField }).first as? UITextField
}
private var searchIcon: UIImage? {
let subViews = subviews.flatMap { [=11=].subviews }
return ((subViews.filter { [=11=] is UIImageView }).first as? UIImageView)?.image
}
private var activityIndicator: UIActivityIndicatorView? {
return textField?.leftView?.subviews.compactMap{ [=11=] as? UIActivityIndicatorView }.first
}
var isLoading: Bool {
get {
return activityIndicator != nil
} set {
let _searchIcon = searchIcon
if newValue {
if activityIndicator == nil {
let _activityIndicator = UIActivityIndicatorView()
_activityIndicator.style = .medium
_activityIndicator.startAnimating()
_activityIndicator.backgroundColor = UIColor.clear
self.setImage(UIImage(), for: .search, state: .normal)
textField?.leftView?.addSubview(_activityIndicator)
let leftViewSize = textField?.leftView?.frame.size ?? CGSize.zero
_activityIndicator.center = CGPoint(x: leftViewSize.width/2, y: leftViewSize.height/2)
}
} else {
self.setImage(_searchIcon, for: .search, state: .normal)
activityIndicator?.removeFromSuperview()
}
}
}
}
iOS13 在 UISearchBar 方面有一些变化,您可以使用 UISearchBar.searchTextField
代替 searchBar.value(forKey: "searchField")
searchBar.searchTextField.backgroundColor = .red
或者如果你想让它与扩展一起工作,你可以这样做:
var searchTextField: UITextField? {
let subViews = self.subviews.first?.subviews.last?.subviews
return subViews?.first as? UITextField
}
我搜索了一整天,但找不到此代码的修复程序。 此扩展将 UISearchField 放大图标替换为 UIActivityView(为真时显示加载图标)
扩展在 iOS 12、Xcode 10.3 上运行良好,但在我更改之后进入 iOS 13, Xcode 11 Beta 4 它停止工作了。
我仍然使用这个做了一个解决方法:
if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField {
let loadingIcon = UIActivityIndicatorView()
loadingIcon.style = .medium
loadingIcon.backgroundColor = UIColor.clear
loadingIcon.startAnimating()
textFieldInsideSearchBar.leftView = loadingIcon
}
但我不明白扩展停止工作的原因。
我还注意到 .flatMap
在 iOS 13 中被 弃用并改为 .compactMap
但是作为我知道没有区别,我已经尝试将 .flatMap
更改为 .compactMap
但仍然没有用。
这是分机:
extension UISearchBar {
private var textField: UITextField? {
let subViews = self.subviews.compactMap { [=11=].subviews }
return (subViews.filter { [=11=] is UITextField }).first as? UITextField
}
private var searchIcon: UIImage? {
let subViews = subviews.flatMap { [=11=].subviews }
return ((subViews.filter { [=11=] is UIImageView }).first as? UIImageView)?.image
}
private var activityIndicator: UIActivityIndicatorView? {
return textField?.leftView?.subviews.compactMap{ [=11=] as? UIActivityIndicatorView }.first
}
var isLoading: Bool {
get {
return activityIndicator != nil
} set {
let _searchIcon = searchIcon
if newValue {
if activityIndicator == nil {
let _activityIndicator = UIActivityIndicatorView()
_activityIndicator.style = .medium
_activityIndicator.startAnimating()
_activityIndicator.backgroundColor = UIColor.clear
self.setImage(UIImage(), for: .search, state: .normal)
textField?.leftView?.addSubview(_activityIndicator)
let leftViewSize = textField?.leftView?.frame.size ?? CGSize.zero
_activityIndicator.center = CGPoint(x: leftViewSize.width/2, y: leftViewSize.height/2)
}
} else {
self.setImage(_searchIcon, for: .search, state: .normal)
activityIndicator?.removeFromSuperview()
}
}
}
}
iOS13 在 UISearchBar 方面有一些变化,您可以使用 UISearchBar.searchTextField
代替 searchBar.value(forKey: "searchField")
searchBar.searchTextField.backgroundColor = .red
或者如果你想让它与扩展一起工作,你可以这样做:
var searchTextField: UITextField? {
let subViews = self.subviews.first?.subviews.last?.subviews
return subViews?.first as? UITextField
}