Using Swift 4, I'm trying to write a custom protocol which provides conformance to an @objc protocol.
Some Code
More specifically, I have a custom protocol Searchable
which provides a simple implementation of the UIKit protocol UISearchBarDelegate
, requiring to only implement a single callback for handling search filter changes.
@objc protocol Searchable: class, UISearchBarDelegate {
@objc func searchFilterChanged(_: String?)
}
I provide the delegate implementation in a protocol extension:
extension Searchable {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchFilterChanged(searchText)
}
// .. and some other delegate methods
}
Finally, in another extension I create and install the search bar (installSearchBar
has to be called from viewDidLoad
of the concrete view controller):
extension Searchable where Self: UITableViewController {
func installSearchBar() {
let searchBar = UISearchBar()
searchBar.delegate = self
tableView?.tableHeaderView = searchBar
}
}
The Problem
Unfortunately, the delegate methods of UISearchBarDelegate
are not called when the user enters text in the search bar. The compiler warns me with this message:
Non-'@objc' method 'searchBar(_:textDidChange:)' does not satisfy optional requirement of '@objc' protocol 'UISearchBarDelegate'
However, I cannot add @objc
to the method because this causes the following compiler error:
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes
The Question
So now my question is: can the desired behavior be implemented in Swift at all, or is it not possible to implement conformance to an @objc protocol in another protocol?
Note 1: I know that this can be implemented using subclass; still I'm looking for a POP version.
Note 2: I know there is UISearchController
which also helps to simplify implementing search; I cannot use this class because in my actual code, I have a more complex filter view with other controls -- that's why I use a bare UISearchBar
.