Настройка UIRefreshControl из UITableView: лучшие практики? - PullRequest
0 голосов
/ 29 марта 2019

У меня есть следующий код, и он работает:

class PullToRefreshTableView: UITableView {
    init(style: UITableView.Style = .plain) {
        super.init(frame: .zero, style: style)
        refreshControl = UIRefreshControl()
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    var first = true
    override func layoutSubviews() {
        defer { super.layoutSubviews() }
        guard first else {
            return
        }

        refreshControl?.addTarget(self, action: #selector(pullToRefresh(refreshControl:)), for: .valueChanged)
    }

    func reset() {
        // Cleaning the table view here
    }

    @objc func pullToRefresh(refreshControl: UIRefreshControl) {
        reset()
        // Then loading more stuff here
    }
}

Что меня беспокоит, так это то, что, поскольку action не регистрируется, когда выполняется в init, мне нужно сделать это позже.Я злоупотребляю layoutSubviews сейчас с флагом bool, и это работает.Однако это ... менее чем идеально.

Есть ли функция или что-то, что я могу переопределить в UITableView (она должна быть автономной), которая будет вызываться только один раз?

После небольшого изменения я получил это:

override func layoutSubviews() {
    defer { super.layoutSubviews() }
    guard !(refreshControl?.allTargets ?? []).contains(self as AnyHashable) else {
        return
    }

    refreshControl?.addTarget(self, action: #selector(pullToRefresh(refreshControl:)), for: .valueChanged)
}

Мне все еще хочется набирать извинения в комментариях, хотя довольно ясно о его намерениях.И не на 100,00% надежнее, поскольку кто-то может добавить действие таргетинга self к этому элементу управления до вызова layoutSubviews.

...