Skip to content

Instantly share code, notes, and snippets.

@serhiybutz
Last active August 18, 2020 21:16
Show Gist options
  • Save serhiybutz/782b6d3b6a92b1848b3d90d0f1faf0a2 to your computer and use it in GitHub Desktop.
Save serhiybutz/782b6d3b6a92b1848b3d90d0f1faf0a2 to your computer and use it in GitHub Desktop.
Combine: withLatestFrom, 03
import UIKit
import Combine
extension UIRefreshControl {
private static var beginRefreshingAssociatedKey = "BeginRefreshingPublisher"
private typealias BeginRefreshingPublisher = PassthroughSubject<Void, Never>
private var internalBeginRefreshingPublisher: BeginRefreshingPublisher {
var publisher = objc_getAssociatedObject(
self,
&UIRefreshControl.beginRefreshingAssociatedKey)
.map { $0 as! BeginRefreshingPublisher }
if publisher == nil {
if Thread.current.isMainThread {
instantiate(&publisher)
} else {
DispatchQueue.main.sync {
instantiate(&publisher)
}
}
}
return publisher!
}
private func instantiate(_ publisher: inout BeginRefreshingPublisher?) {
guard publisher == nil else { return; } // Double-Checked Locking
publisher = BeginRefreshingPublisher()
objc_setAssociatedObject(
self,
&UIRefreshControl.beginRefreshingAssociatedKey,
publisher!,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
self.addTarget(
self,
action: #selector(handleValueChanged), for: .valueChanged)
}
@objc
private func handleValueChanged() {
internalBeginRefreshingPublisher.send()
}
var beginRefreshingPublisher: AnyPublisher<Void, Never> {
internalBeginRefreshingPublisher.eraseToAnyPublisher()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment