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)