RxDataSources icon indicating copy to clipboard operation
RxDataSources copied to clipboard

Custom Collection View Delegate

Open chriskilpin opened this issue 6 years ago • 3 comments

Hi Guys, I was wondering if someone could help. I have a custom CollectionView Layout and a custom CollectionViewDelegate. When I set the delegate via Rx the delgate method the new delegate methods are not being called. What is the best strategy for sorting this out? Do I need to create a new delegete proxy and should that extend from RxScrollViewDelegateProxy or RxCollectionViewDelegateProxy ?

Thanks in advance.

chriskilpin avatar Sep 11 '19 08:09 chriskilpin

Most UIKit delegates like UICollectionViewDelegate have proxies already implemented in RxCocoa. In those cases you can simply do:

collectionView.rx
	.setDelegate(CustomDelegate)
	.disposed(by: bag)

without extending anything. You would implement (and register) a proxy only for 3rd party delegates.

As a side note, repo owner prefer you to use stack overflow or the slack for this kind of question.

AlexisQapa avatar Sep 11 '19 08:09 AlexisQapa

Hi there thanks for the quick response. This is for a 3rd party delegate, my question was around the process of creating and registering the proxy and what it should extend from.

I can move the discussion over to stack overflow if necessary.

chriskilpin avatar Sep 11 '19 09:09 chriskilpin

Try something along those lines:

extension UIDocumentPickerViewController: HasDelegate {
	public typealias Delegate = UIDocumentPickerDelegate
}

private class RxUIDocumentPickerDelegateProxy: DelegateProxy<UIDocumentPickerViewController, UIDocumentPickerDelegate>, DelegateProxyType, UIDocumentPickerDelegate {

	public weak private (set) var controller: UIDocumentPickerViewController?

	public init(controller: ParentObject) {
		self.controller = controller
		super.init(parentObject: controller, delegateProxy: RxUIDocumentPickerDelegateProxy.self)
	}

	static func registerKnownImplementations() {
		self.register { RxUIDocumentPickerDelegateProxy(controller: $0) }
	}
}

extension Reactive where Base: UIDocumentPickerViewController {

	/// Delegate proxy for `UIDocumentPickerViewController`
	public var delegate: DelegateProxy<UIDocumentPickerViewController, UIDocumentPickerDelegate> {
		return RxUIDocumentPickerDelegateProxy.proxy(for: base)
	}

	/// Tells that user has selected one or more documents.
	public var didPickDocumentsAt: Observable<[URL]> {
		return delegate.methodInvoked(#selector(UIDocumentPickerDelegate.documentPicker(_:didPickDocumentsAt:)))
			.map { (values: [Any]) in
				values.last as! [URL]
		}
	}

	/// Tells that user canceled the document picker.
	public var documentPickerWasCancelled: Observable<()> {
		return delegate.methodInvoked(#selector(UIDocumentPickerDelegate.documentPickerWasCancelled(_:)))
			.map {_ in () }
	}
}

If you need further examples try looking at RxSwiftCommunity projects. I remember using those to achieve similar goal.

AlexisQapa avatar Sep 11 '19 12:09 AlexisQapa