我正在尝试制作一个时间表,其中每个部分都是一天,并且每一天都有很多项目(记录)。这是我的部分(日)课:
class YearMonthDay: Comparable, Hashable {
let year: Int
let month: Int
let day: Int
init(year: Int, month: Int, day: Int) {
self.year = year
self.month = month
self.day = day
}
init(date: Date) {
let comps = Calendar.current.dateComponents([.year, .month, .day], from: date)
self.year = comps.year!
self.month = comps.month!
self.day = comps.day!
}
func hash(into hasher: inout Hasher) {
hasher.combine(year)
hasher.combine(month)
hasher.combine(day)
}
var date: Date {
var dateComponents = DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
return Calendar.current.date(from: dateComponents)!
}
static func == (lhs: YearMonthDay, rhs: YearMonthDay) -> Bool {
return lhs.year == rhs.year && lhs.month == rhs.month && lhs.day == rhs.day
}
static func < (lhs: YearMonthDay, rhs: YearMonthDay) -> Bool {
if lhs.year != rhs.year {
return lhs.year < rhs.year
} else {
if lhs.month != rhs.month {
return lhs.month < rhs.month
} else {
return lhs.day < rhs.day
}
}
}
}
正如你所看到的,我正在为我的部分添加年月日属性,并使用它们使每个部分都“可清洗”,因此希望每天最多只有 1 个部分。
这是我的collectionViewController ...
class TimelineViewController: UICollectionViewController {
private lazy var dataSource = makeDataSource()
fileprivate typealias DataSource = UICollectionViewDiffableDataSource<YearMonthDay,TestRecord>
fileprivate typealias DataSourceSnapshot = NSDiffableDataSourceSnapshot<YearMonthDay,TestRecord>
public var data: [YearMonthDay:[TestRecord]] = [:]
var delegate: TimelineViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
guard let data = delegate?.dataForTimelineView() else { return }
self.data = data
collectionView.showsHorizontalScrollIndicator = true
configureHierarchy()
configureDataSource()
applySnapshot()
}
}
extension TimelineViewController {
fileprivate func makeDataSource() -> DataSource {
let dataSource = DataSource(
collectionView: collectionView,
cellProvider: { (collectionView, indexPath, testRecord) ->
UICollectionViewCell? in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TimelineDayCell.identifier, for: indexPath) as? TimelineDayCell
cell?.configure(with: testRecord)
cell?.dayLabel.text = String(indexPath.section)+","+String(indexPath.row)
return cell
})
return dataSource
}
func configureDataSource() {
self.collectionView!.register(TimelineDayCell.nib, forCellWithReuseIdentifier: TimelineDayCell.identifier)
}
func applySnapshot(animatingDifferences: Bool = true) {
// 2
var snapshot = DataSourceSnapshot()
for (ymd,records) in data {
snapshot.appendSections([ymd])
snapshot.appendItems(records,toSection: ymd)
}
// This is where the error occurs.
dataSource.apply(snapshot, animatingDifferences: animatingDifferences)
}
}
但我得到这个崩溃错误:
*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“当集合视图中只有 0 个部分时,请求第 0 部分中的项目数”
如果我查看数据,我可以看到所有数据都已正确填充,并且当我打印出 snapshot.sectionIdentifiers 时,它会为我提供所有这些 YearMonthDay 对象。但不知何故,数据源看到 0 个部分?
我认为对于普通数据源,我只会实现委托方法 - numberOfSections 但由于这是一个可区分的数据源,我不知道该怎么做......
编辑:
来自委托的数据是这种类型的字典:[YearMonthDay:[TestRecord]]。这是打印出来的样子
▿ 7 elements
▿ 0 : 2 elements
▿ key : <YearMonthDay: 0x600000e880f0>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : 5D05C73D-8863-47E3-B1E5-3331791A3FB8
- type : SweatNetOffline.RecordType
- progression : 1
▿ timeStamp : 2020-10-16 04:56:59 +0000
- timeIntervalSinceReferenceDate : 624517019.639298
▿ 1 : 2 elements
▿ key : <YearMonthDay: 0x600000e89ec0>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : C40F5884-AABF-43C8-9921-95DD1423AC4D
- type : SweatNetOffline.RecordType
- progression : 1
▿ timeStamp : 2020-10-22 04:56:59 +0000
- timeIntervalSinceReferenceDate : 625035419.639274
▿ 2 : 2 elements
▿ key : <YearMonthDay: 0x600000e88cf0>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : 5EE70ABF-4C4D-4FB5-A850-3D0081D91D0D
- type : SweatNetOffline.RecordType
- progression : 2
▿ timeStamp : 2020-10-20 04:56:59 +0000
- timeIntervalSinceReferenceDate : 624862619.639284
▿ 3 : 2 elements
▿ key : <YearMonthDay: 0x600000e8a0a0>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : 59152DCA-63EC-4EBF-ACDB-B45FA5E85EED
- type : SweatNetOffline.RecordType
- progression : 2
▿ timeStamp : 2020-10-18 04:56:59 +0000
- timeIntervalSinceReferenceDate : 624689819.639291
▿ 4 : 2 elements
▿ key : <YearMonthDay: 0x600000e89890>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : 0E12D3D6-0650-41A6-AC12-EB75EFA0A151
- type : SweatNetOffline.RecordType
- progression : 0
▿ timeStamp : 2020-10-26 04:56:59 +0000
- timeIntervalSinceReferenceDate : 625381019.638627
▿ 5 : 2 elements
▿ key : <YearMonthDay: 0x600000e89e60>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : 99A929C4-B94B-4F8F-8C6D-2C356D778D95
- type : SweatNetOffline.RecordType
- progression : 2
▿ timeStamp : 2020-10-24 04:56:59 +0000
- timeIntervalSinceReferenceDate : 625208219.639251
▿ 6 : 2 elements
▿ key : <YearMonthDay: 0x600000e89f20>
▿ value : 1 element
▿ 0 : TestRecord
- identifier : EF6EB971-504B-4587-8038-FB8C3FD7ACDC
- type : SweatNetOffline.RecordType
- progression : 1
▿ timeStamp : 2020-10-14 04:56:59 +0000
- timeIntervalSinceReferenceDate : 624344219.639307