微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UICollectionViewDiffableDataSource:当集合视图中只有0个部分时,请求第0部分中的项目数

如何解决UICollectionViewDiffableDataSource:当集合视图中只有0个部分时,请求第0部分中的项目数

我正在尝试创建一个时间表,其中每个部分都是一天,每天都有很多项目(记录)。 这是我的节(天)课:

import activeImage1 from 'somepath...'
import inactiveImage1 from 'somepath...'
import activeImage2 from 'somepath...'
import inactiveImage2 from 'somepath...'
....

const Item = styled.div`
  background-image: ${props => props.src};
  ...other css properties
`

const images = [
  {
    active: activeImage1,inactive: inactiveImage1
  },{
    active: activeImage2,inactive: inactiveImage2
  },....
]

export default function HomePage() {
  const [activeItemIndex,setActiveItemIndex] = useState(0)

  return (
    <div>
      ...some components would call setActiveItemIndex()
      {
        images.map((itemImages,i) => (
          <Item src={activeItemIndex === i ? itemImages.active : itemImages.inactive} />
        ))
      }
    </div>
  )
}

如您所见,我正在将年月日属性添加到我的部分中,并使用它们使每个部分“可水洗”,因此希望每天最多只有1个部分。

这是我的collectionViewController ...

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
            }
        }
    }
}

但是我遇到了崩溃错误

***由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“当集合视图中只有0个部分时,请求第0部分中的项目数”

如果查看数据,我可以看到所有数据都正确填充,并且当我打印出snapshot.sectionIdentifiers时,它为我提供了所有YearMonthDay对象。但是以某种方式datasource看到0个部分?

我认为对于普通的数据源,我只会实现委托方法-numberOfSections,但是由于这是一个可扩散的数据源,我不确定该怎么做...

编辑:

来自委托的

数据是这种类型的字典:[YearMonthDay:[TestRecord]]。这是打印出来的样子

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)
    }
}

解决方法

我对构建collectionView的这种新方式不是很熟悉,但是我相信问题可能是由于这行代码

const Authors = mongoose.model('Authors',schema);
const Authors = mongoose.model('Author',schema); // recommended

为什么要为For循环中的每次迭代在此处传递数组?这应该做一次,不是吗?

snapshot.appendSections([ymd])

for (ymd,records) in data {
      snapshot.appendSections([ymd])
      snapshot.appendItems(records,toSection: ymd)
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。