代码之家  ›  专栏  ›  技术社区  ›  BigBoy1337

为什么在willdisplay单元格中添加reloaddata会阻止滚动单元格出列?

  •  1
  • BigBoy1337  · 技术社区  · 6 年前

    所以我制作了一种时间线,在一个非常宽的水平集合视图中,每天由一个单元格表示。在这里您可以看到/尝试完整的代码 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天的末尾有两个随机生成的日期。在一开始,我使用willdisplay单元格回调滚动到最后一个日期(最近的日期),这恰好是整个collectionview中的最后一个单元格。然后在函数的最后,我执行dayscollectionview.reloaddata()。当这种情况发生时,无论您滚动到哪里,collectionview都会停止对单元格进行出列,cellforitemat将不再被调用。

    值得注意的是,由于整个视图中只有最右端的原始块是蓝色的,如果您向左滚动,它只是清晰的,因为没有任何东西在为单元格着色。为什么这个reloaddata函数会停止这个过程?

    0 回复  |  直到 6 年前