I've been searching all day but couldn't find out a fix for this code. This extension replaces the UISearchField magnifying icon with UIActivityView (shows the loading icon when is true)
The extension was working fine on iOS 12, Xcode 10.3 but after I've changed into iOS 13, Xcode 11 Beta 4 it stopped working.
I've still made a workaround using this:
if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField {
let loadingIcon = UIActivityIndicatorView()
loadingIcon.style = .medium
loadingIcon.backgroundColor = UIColor.clear
loadingIcon.startAnimating()
textFieldInsideSearchBar.leftView = loadingIcon
}
But I can't understand the reason why the extension stopped working.
Also I've noticed that .flatMap
was deprecated in iOS 13 and changed to .compactMap
but as I understood there were no differences, and I've already tried to change the .flatMap
to .compactMap
but still didn't work.
Here is the extension:
extension UISearchBar {
private var textField: UITextField? {
let subViews = self.subviews.compactMap { $0.subviews }
return (subViews.filter { $0 is UITextField }).first as? UITextField
}
private var searchIcon: UIImage? {
let subViews = subviews.flatMap { $0.subviews }
return ((subViews.filter { $0 is UIImageView }).first as? UIImageView)?.image
}
private var activityIndicator: UIActivityIndicatorView? {
return textField?.leftView?.subviews.compactMap{ $0 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()
}
}
}
}
There have been some changes with iOS 13 in terms of UISearchBar, And you can use UISearchBar.searchTextField
instead of searchBar.value(forKey: "searchField")
searchBar.searchTextField.backgroundColor = .red
Or if you want to keep it work with the extension, You can do this:
var searchTextField: UITextField? {
let subViews = self.subviews.first?.subviews.last?.subviews
return subViews?.first as? UITextField
}