DeclarativeHub / Bond

A Swift binding framework
MIT License
4.23k stars 360 forks source link

UICollectionView selected item bidirectional binding issue #682

Open variiance opened 4 years ago

variiance commented 4 years ago

I am trying to do a bidirectional bind between my view controller's collection view and my view model to set an initial value for the selected item and to receive the index of the item later selected by the user. To do this, I've declared var selectedIndex = Observable<IndexPath>(IndexPath(row: 0, section: 0)) in my view model. I am trying to create the binding using viewModel.selectedIndex.bidirectionalBind(to: collectionView.reactive.selectedItemIndexPath)

I get a Expression type 'Reactive<_>' is ambiguous without more context compiler error underlining the collectionView.reactive part of the code. Both Bond and ReactiveKit are imported. I am using Xcode 11.4.1, Bond version 7.6.6. Is my approach correct? What does the error message refer to?

UPDATE: After declaring let reactiveCV = collectionView.reactive separately, the compiler seems to have no issues with the collection view part of the expression. When declaring a bidirectional bind to the selected index with its selectedItemIndexPath property, I get a Cannot invoke 'bidirectionalBind' with an argument list of type '(to: SafeSignal<IndexPath>)' compiler error.

mattboran commented 4 years ago

Disclaimer: I'm not a contributor to this repository but I do use the framework daily at work.

It looks like selectedItemIndexPath (link to source) is not meant to be bound to - it only sends a signal when an item is selected.

It looks like you'll have to have two one-way bindings between your view model and the collection view to achieve the behavior you're looking for. I think you could also write a ReactiveExtension on UICollectionView with a DynamicSubject using the selectedItemIndexPath as the signal and implementing a setter using https://developer.apple.com/documentation/uikit/uicollectionview/1618057-selectitem, if you still wanted to use bidirectional binding.