У меня есть следующий код, и он работает:
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
.