我有一个自定义UICollectionViewCell
,里面有UILabel
。
还有属性hour
,为了示例,它是String?
。
我创建了一个名为bind
的私有函数来配置我的绑定。这是我的班级:
class HourCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var hourLabel UILabel!
let hour Variable<String?> = Variable<String?>("")
let disposeBag: DisposeBag = DisposeBag()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
bind()
}
private func bind() {
hour.asObservable().bind(to: hourLabel.rx.text).disposed(by: disposeBag)
hour.asObservable().subscribe(onNext: {debugPrint("New hour: \($0 ?? "--")")}).disposed(by: disposeBag)
}
}
在所需的init中调用bind
可能是个问题。有时hourLabel
仍未初始化。此外,在init(frame: CGRect)
内调用此函数永远不会触发bind
函数,这很尴尬。我以为这个函数总是被调用。
即使这是一个简单的绑定,我也无法正确实现。
从我的UICollectionViewController
内部,我有这个函数填充我的自定义单元格中的hour
属性:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HourCollectionViewCell", for: indexPath) as! HourCollectionViewCell
var text: String = "\(indexPath.row)"
// This does not work because `bind` method
// is never called.
cell.hour.value = text
return cell
}
更新
我已经看到当我从故事板初始化视图时调用init:coder
,就是这种情况。
我见过here的解决方法是从bind
内拨打layoutSubviews
。一切顺利。这是更好的方法吗?
答案 0 :(得分:2)
您的手机电池是可重复使用的,因此您应该清理处理袋。
class HourCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var hourLabel UILabel!
let hour = PublishRelay<String?>()
private(set) var disposeBag = DisposeBag()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func bind() {
hour.asDriver(onErrorJustReturn: "").debug().drive( hourLabel.rx.text).disposed(by: disposeBag)
}
override prepareForReuse() {
super.prepareForReuse()
disposeBag = DisposeBag()
}
}
我使用了PublishRelay
因为Variable
已被弃用,并将其设为Driver
以确保我们位于mainThread上。
您可以使用debug()
在控制台中打印事件。
因为在重用时我们清除了disposeBag,我们可以在UICollectionViewController中调用bind:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HourCollectionViewCell", for: indexPath) as! HourCollectionViewCell
var text: String = "\(indexPath.row)"
cell.bind()
cell.hour.accept(text)
return cell
}
我建议您查看RxDataSources
,因为UICollectionViewController可能更适合为每个单元格提供模型。