包含使用 RxSwift 的 UICollectionView 的 UITableViewCell
UITableViewCell containing a UICollectionView using RxSwift
我开始在我的 iOS 项目中使用 RxSwift
,我有一个带有自定义 UITableViewCell
subclass 的 UITableView
。在那个子 class 中,我有一个 UICollectionView
.
使用 RxSwift
填充 tableview
非常完美,我为此使用了 RxSwift
的另一个扩展 (RxDataSources)
这是我的做法:
self.dataSource = RxTableViewSectionedReloadDataSource<Section>(configureCell: {(section, tableView, indexPath, data) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCellWithCollectionView
switch indexPath.section {
case 0:
cell.collectionViewCellNibName = "ContactDataItemCollectionViewCell"
cell.collectionViewCellReuseIdentifier = "contactDataItemCellIdentifier"
case 1, 2:
cell.collectionViewCellNibName = "DebtCollectionViewCell"
cell.collectionViewCellReuseIdentifier = "debtCellIdentifier"
default:
break
}
cell.registerNibs(indexPath.section, nativePaging: false, layoutDirection: indexPath.section != 0 ? .horizontal : .vertical)
let cellCollectionView = cell.collectionView!
data.debts.asObservable().bind(to: cellCollectionView.rx.items(cellIdentifier: "debtCellIdentifier", cellType: DebtCollectionViewCell.self)) { row, data, cell in
cell.setup(debt: data)
}
return cell
})
这确实有效。但是当 tableview
单元格滚出屏幕并重新出现时,问题就出现了。这会触发上面的代码块并让应用程序在
时崩溃
data.debts.asObservable().bind(to: cellCollectionView.rx.items(cellIdentifier: "debtCellIdentifier", cellType: DebtCollectionViewCell.self)) { row, data, cell in
cell.setup(debt: data)
}
在同一个 tableview 单元格上被调用两次(有趣的是,甚至 Xcode 崩溃都没有任何痕迹)。
我该怎么做才能避免这种情况?
编辑:
我找到了解决方案,但我必须承认我对它不是很满意...这是我的想法(经过测试并有效)
我在我的 class 中定义了另一个 Dictionary
:
var boundIndizes = [Int: Bool]()
然后我像这样围绕绑定创建一个 if
:
if let bound = self.boundIndizes[indexPath.section], bound == true {
//Do nothing, content is already bound
} else {
data.debts.asObservable().bind(to: cellCollectionView.rx.items(cellIdentifier: "debtCellIdentifier", cellType: DebtCollectionViewCell.self)) { row, data, cell in
cell.setup(debt: data)
}.disposed(by: self.disposeBag)
self.boundIndizes[indexPath.section] = true
}
但我无法相信没有"cleaner"解决方案
问题是每次单元格出列时,您都将 data.debts
绑定到单元格内的 collectionView。
我建议您将与 data.debts
相关的逻辑移动到单元格本身,并声明一个 var disposeBag: DisposeBag
,然后在 prepareForReuse
上重新实例化。请参阅 以供参考。
我开始在我的 iOS 项目中使用 RxSwift
,我有一个带有自定义 UITableViewCell
subclass 的 UITableView
。在那个子 class 中,我有一个 UICollectionView
.
使用 RxSwift
填充 tableview
非常完美,我为此使用了 RxSwift
的另一个扩展 (RxDataSources)
这是我的做法:
self.dataSource = RxTableViewSectionedReloadDataSource<Section>(configureCell: {(section, tableView, indexPath, data) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCellWithCollectionView
switch indexPath.section {
case 0:
cell.collectionViewCellNibName = "ContactDataItemCollectionViewCell"
cell.collectionViewCellReuseIdentifier = "contactDataItemCellIdentifier"
case 1, 2:
cell.collectionViewCellNibName = "DebtCollectionViewCell"
cell.collectionViewCellReuseIdentifier = "debtCellIdentifier"
default:
break
}
cell.registerNibs(indexPath.section, nativePaging: false, layoutDirection: indexPath.section != 0 ? .horizontal : .vertical)
let cellCollectionView = cell.collectionView!
data.debts.asObservable().bind(to: cellCollectionView.rx.items(cellIdentifier: "debtCellIdentifier", cellType: DebtCollectionViewCell.self)) { row, data, cell in
cell.setup(debt: data)
}
return cell
})
这确实有效。但是当 tableview
单元格滚出屏幕并重新出现时,问题就出现了。这会触发上面的代码块并让应用程序在
data.debts.asObservable().bind(to: cellCollectionView.rx.items(cellIdentifier: "debtCellIdentifier", cellType: DebtCollectionViewCell.self)) { row, data, cell in
cell.setup(debt: data)
}
在同一个 tableview 单元格上被调用两次(有趣的是,甚至 Xcode 崩溃都没有任何痕迹)。
我该怎么做才能避免这种情况?
编辑:
我找到了解决方案,但我必须承认我对它不是很满意...这是我的想法(经过测试并有效)
我在我的 class 中定义了另一个 Dictionary
:
var boundIndizes = [Int: Bool]()
然后我像这样围绕绑定创建一个 if
:
if let bound = self.boundIndizes[indexPath.section], bound == true {
//Do nothing, content is already bound
} else {
data.debts.asObservable().bind(to: cellCollectionView.rx.items(cellIdentifier: "debtCellIdentifier", cellType: DebtCollectionViewCell.self)) { row, data, cell in
cell.setup(debt: data)
}.disposed(by: self.disposeBag)
self.boundIndizes[indexPath.section] = true
}
但我无法相信没有"cleaner"解决方案
问题是每次单元格出列时,您都将 data.debts
绑定到单元格内的 collectionView。
我建议您将与 data.debts
相关的逻辑移动到单元格本身,并声明一个 var disposeBag: DisposeBag
,然后在 prepareForReuse
上重新实例化。请参阅