Swift 4中TableView绑定两个单元格的实现求助
看了你给出的代码片段,结合日常用RxSwift做TableView绑定的踩坑经验,我整理了几个最可能的问题点和对应的解决办法,帮你定位问题:
首先先把你给出的代码片段整理出来方便参考:
private func bindCells() { viewModel.address.asObservable() .bind(to: TableView.rx.items(cellIdentifier: AccountShippingCell.Identifier, cellType: AccountShippingCell.self)) { row, address, cell in cell.address = address }.disposed(by: disposeBag) viewModel.payment.asObservable() // 这里应该是你未完成的payment数据源绑定逻辑 }
常见问题排查与解决
检查TableView的引用是否正确
你代码里写的TableView是类名还是ViewController里的IBOutlet实例?如果是类名的话肯定会报错,必须用你拖线创建的实例变量,比如改成tableView.rx.items(假设你的IBOutlet叫tableView)。确认单元格注册是否正确完成
虽然你说已经注册了单元格,但要确保注册方式和绑定用的标识符完全匹配:// 如果是纯代码创建的单元格 tableView.register(AccountShippingCell.self, forCellReuseIdentifier: AccountShippingCell.Identifier) // 如果是xib创建的单元格,要用这个方法 tableView.register(UINib(nibName: "AccountShippingCell", bundle: nil), forCellReuseIdentifier: AccountShippingCell.Identifier)注册操作建议放在
viewDidLoad里执行,确保在绑定之前完成。验证ViewModel的Observable序列是否正常发事件
有时候绑定没效果是因为数据源根本没发出数据,你可以给Observable加个debug()来查看控制台输出:viewModel.address.asObservable() .debug("Address数据源日志") .bind(to: tableView.rx.items(...)) ...如果控制台看不到
next事件,那就要去检查ViewModel里的address序列有没有调用onNext传递数据。检查自定义单元格的属性实现
确保AccountShippingCell里的address属性设置后能正确更新UI,比如:class AccountShippingCell: UITableViewCell { static let Identifier = "AccountShippingCell" @IBOutlet weak var addressLabel: UILabel! var address: AddressModel? { didSet { guard let addr = address else { return } addressLabel.text = "\(addr.street), \(addr.city)" // 这里要把数据映射到对应的UI控件上 } } }要是
didSet里没做UI更新,就算绑定成功也看不到内容。确认DisposeBag的生命周期
一定要保证disposeBag是ViewController的实例变量,不能是bindCells()方法里的局部变量,否则绑定会被立即释放:class YourViewController: UIViewController { private let disposeBag = DisposeBag() // 这里是实例变量,正确 override func viewDidLoad() { super.viewDidLoad() bindCells() } }
额外提示:如果要绑定多个数据源到同一个TableView
如果你的address和payment是两个独立的数据源,想在同一个TableView里展示,直接分开绑定是不行的(一个TableView只能绑定一个数据源)。这种情况需要把两个数据源合并,比如用combineLatest包装成统一的序列:
// 先定义枚举区分两种数据类型 enum CellDataType { case shipping(AddressModel) case payment(PaymentModel) } // 在ViewModel里合并两个序列 var combinedData: Observable<[CellDataType]> { return Observable.combineLatest(address.asObservable(), payment.asObservable()) { addresses, payments in var result = [CellDataType]() addresses.forEach { result.append(.shipping($0)) } payments.forEach { result.append(.payment($0)) } return result } } // 然后统一绑定到TableView viewModel.combinedData.asObservable() .bind(to: tableView.rx.items) { tableView, row, data in switch data { case .shipping(let addr): let cell = tableView.dequeueReusableCell(withIdentifier: AccountShippingCell.Identifier) as! AccountShippingCell cell.address = addr return cell case .payment(let pay): let cell = tableView.dequeueReusableCell(withIdentifier: AccountPaymentCell.Identifier) as! AccountPaymentCell cell.payment = pay return cell } }.disposed(by: disposeBag)
内容的提问来源于stack exchange,提问作者Diego

