Short description of the issue:
I'm trying to use RXSwift in my UICollectionView Source. I've already setup the rx.setDelegate(self) to my class but the methods like
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
is never called.
Self contained code example that reproduces the issue:
My Datasource Class using RX implementation
class ProductDataSource: NSObject, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
private let products: Variable<Array<CartProduct>>
private let bag = DisposeBag()
private let collectionView: UICollectionView
init(_ collectionView: UICollectionView, products: Variable<Array<CartProduct>>) {
self.collectionView = collectionView
self.products = products
super.init()
}
func prepareSource() {
collectionView.rx.setDelegate(self)
.addDisposableTo(bag)
products.asObservable()
.bindTo(collectionView.rx.items) { (tableView, row, element) in
let indexPath = IndexPath(row: row, section: 0)
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BaseProductCell
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.whiteSmokeColor.cgColor
cell.layer.cornerRadius = 5
cell.test.text = "\(row) :: \(element.product.id)"
return cell
}
.addDisposableTo(bag)
}
}
Calling in controller:
private var source: ProductDataSource?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
source = ProductDataSource(self.collection, products: SharedCart.shared.products)
source?.prepareSource()
self.touched(BaseProduct())
}
Extension for delegate methods:
extension ProductDataSource {
// Collection view flow layout setup
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let screenSize = UIScreen.main.bounds
let screenWidth = screenSize.width
let cellSquareSize: CGFloat = (screenWidth / 2.0) - 10
return CGSize.init(width: cellSquareSize, height: 240.0)
}
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(5, 5, 5, 5)
}
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 5
}
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 5
}
}
Xcode version:
v8.0
Expected outcome:
Delegate methods should be called. There are already 10+ products in my list.
What actually happens:
Delegate methods are not called.
Installation method:
I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)
Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)
I've resolved this issue. Method definitions were not compatible with Swift 3.
New Extension looks like:
extension ProductDataSource {
@objc(collectionView:layout:sizeForItemAtIndexPath:)
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let screenSize = UIScreen.main.bounds
let screenWidth = screenSize.width
let cellSquareSize: CGFloat = (screenWidth / 2.0) - 10
return CGSize.init(width: cellSquareSize, height: 240.0)
}
@objc(collectionView:layout:insetForSectionAtIndex:)
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(5, 5, 5, 5)
}
@objc(collectionView:layout:minimumLineSpacingForSectionAtIndex:)
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
@objc(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}
Most helpful comment
I've resolved this issue. Method definitions were not compatible with Swift 3.
New Extension looks like: