Issue #20
The other day I was doing refresh control, and I saw this Swift Protocols with Default Implementations as UI Mixins
extension Refreshable where Self: UIViewController
{
/// Install the refresh control on the table view
func installRefreshControl()
{
let refreshControl = UIRefreshControl()
refreshControl.tintColor = .primaryColor
refreshControl.addTarget(self, action: #selector(handleRefresh(_:)), for: .valueChanged)
self.refreshControl = refreshControl
if #available(iOS 10.0, *)
{
tableView.refreshControl = refreshControl
}
else
{
tableView.backgroundView = refreshControl
}
}
}
Protocol extension is cool but somehow I’m not a fan of it. I always consider composition first, to extract the specific task to one entity that does that well. It looks like this
class RefreshHandler: NSObject {
let refresh = PublishSubject<Void>()
let refreshControl = UIRefreshControl()
init(view: UIScrollView) {
super.init()
view.addSubview(refreshControl)
refreshControl.addTarget(self, action: #selector(refreshControlDidRefresh(_: )), for: .valueChanged)
}
// MARK: - Action
func refreshControlDidRefresh(_ control: UIRefreshControl) {
refresh.onNext(())
}
func end() {
refreshControl.endRefreshing()
}
}
It is a bit Rx
, we can use block if we like, but the idea is we can declare this RefreshHandler
and use it everywhere we want
refreshHandler = RefreshHandler(view: scrollView)
refreshHandler.refresh
.startWith(())
.bindTo(viewModel.input.fetch)
.addDisposableTo(bag)