如何使用 RxSwift 和 RxSwiftDataSources 将表视图与表示不同数据类型的多个部分绑定?
Posted
技术标签:
【中文标题】如何使用 RxSwift 和 RxSwiftDataSources 将表视图与表示不同数据类型的多个部分绑定?【英文标题】:How to bind table view with multiple sections that represent different data types using RxSwift and RxSwiftDataSources? 【发布时间】:2016-11-06 23:41:08 【问题描述】:我正在尝试使用 RxSwift 创建一个包含多个部分的表格视图。每个部分显示代表不同类型的数据。
我找到了RxSwiftDataSources
库并从他们的文档中实现了示例。
以下是该示例如何实现的快速概览:
定义了一个自定义数据类型CustomData
:
struct CustomData
var anInt: Int
var aString: String
var aCGPoint: CGPoint
然后,添加该部分的表示(注意这里实现了SectionModelType
):
struct SectionOfCustomData
var header: String
var items: [Item]
extension SectionOfCustomData: SectionModelType
typealias Item = CustomData
init(original: SectionOfCustomData, items: [Item])
self = original
self.items = items
最后,创建了一些示例数据并将其绑定到表格视图:
let sections: [SectionOfCustomData] = [
SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]),
SectionOfCustomData(header: "Second section", items: [CustomData(anInt: 2, aString: "two", aCGPoint: CGPoint(x: 2, y: 2)), CustomData(anInt: 3, aString: "three", aCGPoint: CGPoint(x: 3, y: 3)) ])
]
我现在想修改示例,只想在第二部分显示String
s 而不是CustomData
的实例,所以有点像这样:
let sections = [
SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]),
SectionOfString(header: "Second section", items: ["a", "b", "c"])
]
这显然不会编译,因为 sections
现在包含不同类型的元素 SectionOfCustomData
和 SectionOfString
。我试图通过尝试将部分声明为[SectionModelType]
来解决此问题,但这不起作用,编译器抱怨:
Protocol 'SectionModelType
' 只能用作通用约束,因为它具有 Self 或关联的类型要求
【问题讨论】:
您已经找到解决方案了吗? 【参考方案1】:您可以使用枚举来包装不同的类型。
使用枚举,SectionOfCustomData 定义应该是这样的:
enum SectionOfCustomData: SectionModelType
typealias Item = Row
case customDataSection(header: String, items: [Row])
case stringSection(header: String, items: [Row])
enum Row
case customData(customData: CustomData) // wrapping CustomData to Row type
case string(string: String) // wrapping String to Row type
// followings are not directly related to this topic, but represents how to conform to SectionModelType
var items: [Row]
switch self
case .customDataSection(_, let items):
return items
case .stringSection(_, let items):
return items
public init(original: SectionOfCustomData, items: [Row])
switch self
case .customDataSection(let header, _):
self = .customDataSection(header: header, items: items)
case .stringSection(let header, _):
self = .stringSection(header: header, items: items)
configureCell 看起来像这样:
let dataSource = RxTableViewSectionedReloadDataSource<SectionOfCustomData>()
...
dataSource.configureCell = [weak self] (dataSource, tableView, indexPath, row) -> UITableViewCell in
switch dataSource[indexPath]
case .customData(let customData):
let cell: CustomDataCell = // dequeue cell
self?.configure(cell: cell, with: customData)
return cell
case .string(let string):
let cell: StringCell = // dequeue cell
self?.configure(cell: cell, with: string)
return cell
【讨论】:
在init
中应该是switch original
而不是switch self
?以上是关于如何使用 RxSwift 和 RxSwiftDataSources 将表视图与表示不同数据类型的多个部分绑定?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 MVVM 和 RxSwift 编辑/删除 UICollectionView 单元格
如何使用 RxSwift 的 RXBluetoothKit 结合写入特性和特性通知