为什么在willDisplay单元格中添加reloadData可以防止单元格在滚动时出队?

时间:2018-10-10 22:58:05

标签: ios swift uicollectionview

因此,我正在制定一种时间表,其中每天由一个非常宽的水平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函数将停止此过程?

0 个答案:

没有答案