Сброс UITableViewCell Не работает должным образом / после выбора прокрутки отображаются выбранные ячейки

Проблема в том, когда я прокручиваю табличное представление после выбора collectionViewCell (фиолетовый цвет на дате 28). Похоже, что несколько CollectionViewCells внизу табличного представления выбраны (здесь CollectionView присутствует внутри TableView).

Код выглядит так:

class ViewController: UIViewController {

    @IBOutlet weak var tblView: UITableView!

    var storedOffsets = [Int: CGFloat]()           // Will be used by JTAppleCalender
    let formatter = DateFormatter()                // NSDateFormatter


    override func viewDidLoad() {
        super.viewDidLoad()

        self.tblView.delegate = self
        self.tblView.dataSource = self
        self.tblView.reloadData()
    }

    func handleCellConfiguration(cell: JTAppleCell?, cellState: CellState) {
        handleCellSelection(view: cell, cellState: cellState)
    }


    func handleCellSelection(view: JTAppleCell?, cellState: CellState) {

        guard let myCustomCell = view as? CalenderCell else {return }
        if cellState.isSelected {
            myCustomCell.contentView.layer.cornerRadius = 10
            myCustomCell.contentView.backgroundColor = UIColor.init(red: 0.26, green: 0.10, blue: 0.39, alpha: 1.0)
        } else {
            myCustomCell.contentView.layer.cornerRadius =  0
            myCustomCell.contentView.backgroundColor = UIColor.clear
        }
    }
}

UITableViewCell:

class TableCell: UITableViewCell{

    @IBOutlet weak var lbldate: UILabel!
    @IBOutlet weak var collectionViewDate: JTAppleCalendarView!


    override func prepareForReuse() {
        super.prepareForReuse()

      }
}

extension TableCell {

    func setCollectionViewDataSourceDelegate<D: JTAppleCalendarViewDataSource & JTAppleCalendarViewDelegate>(_ dataSourceDelegate: D, forRow row: Int) {

        collectionViewDate.calendarDelegate = dataSourceDelegate
        collectionViewDate.calendarDataSource = dataSourceDelegate
        collectionViewDate.tag = row
        collectionViewDate.setContentOffset(collectionViewDate.contentOffset, animated:false)
        collectionViewDate.reloadData()
    }

    var collectionViewOffset: CGFloat {
        set { collectionViewDate.contentOffset.x = newValue }
        get { return collectionViewDate.contentOffset.x }
    }
}


extension ViewController : UITableViewDataSource, UITableViewDelegate{

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 7
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = self.tblView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell

        cell.lbldate.text = "date "+"\(indexPath.row)"
        return cell
    }


    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        guard let tableViewCell = cell as? TableCell else { return }
        tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
        tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
    }

    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        guard let tableViewCell = cell as? TableCell else { return }
        storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
    }

}


class CalenderCell: JTAppleCell{

    @IBOutlet weak var lblDate: UILabel!
}




extension ViewController: JTAppleCalendarViewDataSource , JTAppleCalendarViewDelegate {


    func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {
        let myCustomCell = cell as! CalenderCell
        sharedFunctionToConfigureCell(myCustomCell: myCustomCell, cellState: cellState, date: date)
    }

    func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {

        let cell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: "CalenderCell", for: indexPath) as! CalenderCell
        cell.lblDate.text = cellState.text
        self.calendar(calendar, willDisplay: cell, forItemAt: date, cellState: cellState, indexPath: indexPath)

        return cell
    }

    func calendar(_ calendar: JTAppleCalendarView, didDeselectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
        handleCellConfiguration(cell: cell, cellState: cellState)
    }

    func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {

        handleCellConfiguration(cell: cell, cellState: cellState)
    }

    func sharedFunctionToConfigureCell(myCustomCell: CalenderCell, cellState: CellState, date: Date) {
        handleCellConfiguration(cell: myCustomCell, cellState: cellState)
    }

    func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {

        let currentDate = Date()
        let endDate = Calendar.current.date(byAdding: .month, value: 4, to: Date())
        let parameters = ConfigurationParameters(startDate: currentDate,
                                                 endDate: endDate!,
                                                 numberOfRows: 1,
                                                 generateInDates: .forFirstMonthOnly,
                                                 generateOutDates: .off,
                                                 hasStrictBoundaries: false)
        calendar.scrollToDate(currentDate, triggerScrollToDateDelegate: false, animateScroll: false)
        return parameters
    }

    func configureVisibleCell(myCustomCell: CalenderCell, cellState: CellState, date: Date) {
        handleCellConfiguration(cell: myCustomCell, cellState: cellState)
    }

}

Дайте мне знать, если мне нужно добавить что-нибудь еще.

3 ответа

Решение

Это не рекомендуемый способ работы с JTAppleCalendar CollectionView. Вы должны сохранить даты, выбранные в некоторой переменной источника данных, и когда ячейка выбрана / снята. При перезагрузке, основываясь на этих сохраненных значениях, вы должны соответственно выделить ячейку.

//This will store the selected dates against the cell rows.
var selectedDatesVsIndex = [Int : Date]()

В методах выбора / отмены делегата JTAppleCalendar добавьте выбранные даты в localDictionary, который поддерживает rowIndex -> DateSelected.

   func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
        cell?.isSelected = true
        selectedDatesVsIndex.merge([calendar.tag : date]) { (d1, d2) -> Date in return d1 }

        calendar.reloadData()
//        handleCellConfiguration(cell: cell, cellState: cellState)
    }


  func calendar(_ calendar: JTAppleCalendarView, didDeselectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
        cell?.isSelected = false
        selectedDatesVsIndex.removeValue(forKey: calendar.tag)
        calendar.reloadData()

//        handleCellConfiguration(cell: cell, cellState: cellState)
    }

Кроме того, я установил тег как indexpath.row в TableViewCells. Также добавьте метод перезагрузки представления коллекции. Как это

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = self.tblView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
        cell.tag = indexPath.row
        cell.collectionViewDate.tag = indexPath.row
        cell.collectionViewDate.reloadData()

        cell.lbldate.text = "date "+"\(indexPath.row)"
        return cell
    }

Настройка ячейки для отображения выбранного цвета фона должна быть сделана в CellForRowAt Index.

 func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {

        let cell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: "CalenderCell", for: indexPath) as! CalenderCell
        cell.lblDate.text = cellState.text
        cell.backgroundColor =  UIColor.clear

        if selectedDatesVsIndex.keys.index(of: calendar.tag) != nil {
            if let object = selectedDatesVsIndex[calendar.tag] , object.compare(date) == .orderedSame {
                cell.backgroundColor = UIColor.gray
            }
        }
 //       self.calendar(calendar, willDisplay: cell, forItemAt: date, cellState: cellState, indexPath: indexPath)

        return cell
    }

Пожалуйста, удалите другие методы, такие как беспорядок

 override func prepareForReuse() {
        super.prepareForReuse()

//        let hasContentView = self.subviews .contains(self.contentView)
//        if(hasContentView){
//            self.contentView.removeFromSuperview()
//        }
    }

Пожалуйста, проверьте, присутствует ли значение в конкретном indexpath или нет. Если в качестве значения указано make, то при выборе оно устранит проблему с перекрытием.

Просто измените цвет в методе (cellForRowAt indexPath: IndexPath) вместо handleCellSelection(view: JTAppleCell?, cellState: CellState)

Как это:-

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = self.tblView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell

        cell.lbldate.text = "date "+"\(indexPath.row)"

         if cell.isSelected == true
        {
         cell.contentView.layer.cornerRadius = 10
            cell.contentView.backgroundColor = UIColor.init(red: 0.26, green: 0.10, blue: 0.39, alpha: 1.0)   

        }
   else
   {
cell.contentView.layer.cornerRadius = 0
 cell.contentView.backgroundColor = UIColor.clear
    }
        return cell
 }

И создайте код для выбора ячейки по методу didSelect.

Другие вопросы по тегам