自我调整collectionViewCells使用RxDataSource

时间:2017-03-03 21:08:08

标签: rx-swift rxdatasources

如何使用RxDataSource实现自我调整collectionViewCells?

我尝试过设置

flowLayout.estimatedItemSize = CGSize(width: 187, height: 102)

但是当dataSourceObservable发生变化时,应用会崩溃。

我已尝试在

中设置单元格大小
dataSource.configureCell = { [weak self] (dataSource, collectionView, indexPath, _) in 

这不是一个好主意,因为细胞重叠,这是因为我没有使用

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize

现在,可以仅使用observable正确布局单元格大小吗?那不是叫做像

这样的东西
dataSourceVar.value[indexPath].cellSize

collectionView sizeForItemAt内?

1 个答案:

答案 0 :(得分:0)

将收藏夹视图添加到情节提要。导入RxDataSources作为依赖项。

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ViewController: UIViewController {

  private let disposeBag = DisposeBag()

  @IBOutlet weak var collectionView: UICollectionView!
  @IBOutlet weak var collectionLayout: UICollectionViewFlowLayout! {
    didSet {
      collectionLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
    }
  }

  private let section = BehaviorRelay(
    value: Section(items: [
      Item(title: "Lorem ipsum dolor sit amet, consectetur"),
      Item(title: "adipiscing elit, sed do eiusmod tempor"),
      Item(title: "incididunt ut labore et dolore magna aliqua"),
      Item(title: "Ut enim ad minim veniam"),
      Item(title: "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."),
      Item(title: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
      ]
    )
  )

  private lazy var collectionDatasource = {
    return RxCollectionViewSectionedReloadDataSource<Section>(
      configureCell: { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionCell
        cell.titleLabel.text = item.title
        cell.layer.borderWidth = 0.5
        cell.layer.borderColor = UIColor.lightGray.cgColor
        cell.maxWidth = collectionView.bounds.width - 16
        return cell
    })
  }()

  override func viewDidLoad() {
    super.viewDidLoad()

    initCollection()
  }

  private func initCollection() {
    section
      .asObservable()
      .map({ return [$0] })
      .bind(to: collectionView.rx.items(dataSource: collectionDatasource))
      .disposed(by: disposeBag)
  }
}

数据模型

import Foundation

struct Item {
  let title: String
}

创建Section类的子类SectionModelType

导入RxDataSources

struct Section {
  var items: [Item]
}

extension Section: SectionModelType {

  init(
    original: Section,
    items: [Item]) {

    self = original
    self.items = items
  }
}

集合视图单元格类

import UIKit

class CollectionCell: UICollectionViewCell {
    @IBOutlet weak var titleLabel: UILabel!

    // Note: must be strong
    @IBOutlet private var maxWidthConstraint: NSLayoutConstraint! {
        didSet {
            maxWidthConstraint.isActive = false
        }
    }

    var maxWidth: CGFloat? = nil {
        didSet {
            guard let maxWidth = maxWidth else {
                return
            }
            maxWidthConstraint.isActive = true
            maxWidthConstraint.constant = maxWidth
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        contentView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            contentView.leftAnchor.constraint(equalTo: leftAnchor),
            contentView.rightAnchor.constraint(equalTo: rightAnchor),
            contentView.topAnchor.constraint(equalTo: topAnchor),
            contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
            ])
    }

}