iOS: UIActivityIndicator in UISearchBar
Found none of the advertised solutions worked well for iOS13... here is my own, which subclasses the Search Bar and should be more robust for future use
class SearchBar: UISearchBar {
var activityIndicator: UIActivityIndicatorView?
var isLoading: Bool {
get {
return activityIndicator != nil
} set {
if newValue {
if activityIndicator == nil {
guard let leftView = searchTextField.leftView else {
return
}
let ai = UIActivityIndicatorView(style: .medium)
ai.frame = self.convert(leftView.frame, from: leftView.superview)
self.addSubview(ai)
ai.startAnimating()
leftView.isHidden = true
activityIndicator = ai
}
} else {
activityIndicator?.removeFromSuperview()
activityIndicator = nil
guard let leftView = searchTextField.leftView else {
return
}
leftView.isHidden = false
}
}
}
}
Update for iOS 13.
You can use below extension in Swift 4+. Usage:
To show activity :
searchBar.isLoading = true
To hide activity :
searchBar.isLoading = false
UISearchBar Extension
extension UISearchBar {
public var textField: UITextField? {
if #available(iOS 13.0, *) {
return self.searchTextField
} else {
let subViews = subviews.flatMap { $0.subviews }
guard let textField = (subViews.filter { $0 is UITextField }).first as? UITextField else {
return nil
}
return textField
}
}
public var activityIndicator: UIActivityIndicatorView? {
return textField?.leftView?.subviews.flatMap{ $0 as? UIActivityIndicatorView }.first
}
var isLoading: Bool {
get {
return activityIndicator != nil
} set {
if newValue {
if activityIndicator == nil {
let newActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
newActivityIndicator.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
newActivityIndicator.startAnimating()
newActivityIndicator.backgroundColor = UIColor.white
textField?.leftView?.addSubview(newActivityIndicator)
let leftViewSize = textField?.leftView?.frame.size ?? CGSize.zero
newActivityIndicator.center = CGPoint(x: leftViewSize.width/2, y: leftViewSize.height/2)
}
} else {
activityIndicator?.removeFromSuperview()
}
}
}
}
Yes you can.
When start searching create an activity indicator and add it as the subview of UISearchBar
using addSubView
method. When you finish the search remove it from the search bar using removeFromSuperView
method.
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
//set frame for activity indicator
[searchBar addSubview: spinner];
[spinner startAnimating];
Refer this link for an alternative way.