因此,我正在制定一种时间表,其中每天由一个非常宽的水平collectionView中的1个单元格表示。在这里,您可以查看/尝试完整的代码https://github.com/AlexMarshall12/singleDayTimeline.git。它也复制在下面
let cellIdentifier = "DayCollectionViewCell"
class ViewController: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate {
@IBOutlet weak var button: UIButton!
var dates = [Date?]()
var startDate: Date?
var endDate: Date?
private var selectedIndexPath: IndexPath?
@IBOutlet weak var daysCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
daysCollectionView.register(UINib.init(nibName: "DayCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: cellIdentifier)
let allDates = Helper.generateRandomDate(daysBack: 900, numberOf: 10)
self.dates = allDates.sorted(by: {
$0!.compare($1!) == .orderedAscending
})
self.startDate = Calendar.current.startOfDay(for: dates.first as! Date)
self.endDate = dates.last!
self.dates = Array(dates.suffix(from: 8))
print(self.dates)
daysCollectionView.delegate = self
daysCollectionView.dataSource = self
}
var onceOnly = false
internal func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if !onceOnly {
//let lastDateIndexPath = IndexPath(row: dates.count - 1,section: 0)
let lastDate = dates.last
let lastDayIndex = lastDate!?.interval(ofComponent: .day, fromDate: startDate!)
let lastDayCellIndexPath = IndexPath(row: lastDayIndex!, section: 0)
self.daysCollectionView.scrollToItem(at: lastDayCellIndexPath, at: .left, animated: false)
self.selectedIndexPath = lastDayCellIndexPath
self.daysCollectionView.reloadData() //LINE IN QUESTION
onceOnly = true
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let days = self.endDate!.days(from: self.startDate!)
if days <= 150 {
return 150
} else {
print(days,"days")
return days + 1
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = daysCollectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! DayCollectionViewCell
let cellDate = Calendar.current.date(byAdding: .day, value: indexPath.item, to: self.startDate!)
if let selectedRow = selectedIndexPath {
cell.reloadCell(selectedRow==indexPath)
} else {
cell.reloadCell(false)
}
if Calendar.current.component(.day, from: cellDate!) == 15 {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM"
let monthString = dateFormatter.string(from: cellDate!)
cell.drawMonth(month: monthString)
}
if Calendar.current.component(.day, from: cellDate!) == 1 && Calendar.current.component(.month, from: cellDate!) == 1 {
print("drawYEAR")
cell.drawYear(year:Calendar.current.component(.year, from: cellDate!))
}
if self.dates.contains(where: { Calendar.current.isDate(cellDate!, inSameDayAs: $0!) }) {
print("same")
cell.backgroundColor = UIColor.red
}
cell.backgroundColor = UIColor.blue
return cell
}
@IBAction func buttonPressed(_ sender: Any) {
let randomIndex = Int(arc4random_uniform(UInt32(self.dates.count)))
let randomDate = self.dates[randomIndex]
let daysFrom = randomDate?.days(from: self.startDate!)
let indexPath = IndexPath(row: daysFrom!, section: 0)
self.selectedIndexPath = indexPath;
//daysCollectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredHorizontally)
daysCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
daysCollectionView.reloadData()
}
}
因此,在当前日期之前900天的末尾有2个随机生成的日期。首先,我将使用willDisplay单元格回调滚动到最后一个日期(最近的日期),该日期恰好是整个collectionView中的最后一个单元格。然后在该函数的最后,执行daysCollectionView.reloadData()。发生这种情况时,无论在何处滚动,collectionView都会停止对单元格进行出队,永远不会再次调用cellForItemAt。
值得注意的是,您可以知道,因为整个视图的原始最右边的块仅显示为蓝色,如果向左滚动,则可以清楚地看到,因为不再有任何颜色使单元格着色。为什么此reloadData函数将停止此过程?