UICollectionView reloadData () в SwipeGestureRecognizer не работает - PullRequest
0 голосов
/ 29 сентября 2019

Я работаю над проектом, где мне нужно горизонтальное представление календаря в верхней части экрана. В этом календаре будет отображаться общее количество 7 дат (с понедельника по воскресенье с датой). Чтобы получить следующую неделю, я использовал SwipeGestureRecognizer, чтобы определить, проводил ли пользователь пальцем влево или вправо, и поэтому неделя добавляется к текущей отображаемой неделе или вычитается. Моя проблема в том, что считывания считываются правильно, и вычисления для получения новой недели работают (они печатаются в консоли), но каким-то образом UICollectionView не выполняет reloadData (), которую я вызываю после того, как все 7 дней новой неделивычисляется и сохраняется в массиве, который я использую для заполнения своего UICollectionView.

Для лучшего понимания я добавил свой код SwipeWeekView и ViewController, который содержит экземпляр этого SwipeWeekView.

Заранее спасибо!

SwipeWeekView.swift

class SwipeWeekView: UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    let calendar = Calendar.current
    let weekdayAbreviation = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]
    var days = [Date]()
    var today = Date()
    var mondayOfCurrentWeek = Date()
    let formatter = DateFormatter()
    var dayOffset: Int = 0
    var swipeIndex: Int = 0


    lazy var collectionView: UICollectionView = {
           let layout = UICollectionViewFlowLayout()
           layout.scrollDirection = .horizontal
           let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
           cv.backgroundColor = .white
           cv.translatesAutoresizingMaskIntoConstraints = false
           cv.allowsMultipleSelection = false
            cv.showsHorizontalScrollIndicator = false
           return cv
       }()


    override init(frame: CGRect) {
        super.init(frame: frame)

        setupView()
    }

    func setupView() {
        addSubview(collectionView)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(DateCell.self, forCellWithReuseIdentifier: cellId)

        collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        collectionView.heightAnchor.constraint(equalToConstant: 75).isActive = true

        setupCalendar()
        setupSwipeGestureRecognizer()
    }

    func setupCalendar() {
        today = calendar.startOfDay(for: Date())
        formatter.dateFormat = "dd"
        let temp = getCurrentWeekday(date: today)
        mondayOfCurrentWeek = getMondayOfCurrentWeek(weekdayNumber: temp, currentDate: today)
        days = getAllWeekdaysOfCurrentWeek(startDate: mondayOfCurrentWeek)
    }

    func getCurrentWeekday(date: Date) -> Int {
        return calendar.component(.weekday, from: date)
    }

    func getDateOffset(by: Int) -> Int{
        switch by {
        case 1:
            dayOffset = 1
            break
        case 2:
            dayOffset = 0
            break
        case 3:
            dayOffset = -1
            break
        case 4:
            dayOffset = -2
            break
        case 5:
            dayOffset = -3
            break
        case 6:
            dayOffset = -4
            break
        case 7:
            dayOffset = -5
            break
        case 8:
            dayOffset = -6
            break
        default:
            break
        }
        return dayOffset
    }

    func getMondayOfCurrentWeek(weekdayNumber: Int, currentDate: Date) -> Date {
        let dateOffSet = getDateOffset(by: weekdayNumber)
        let calculatedMonday = calendar.date(byAdding: .day, value: dateOffSet, to: currentDate)!
       return calculatedMonday
    }

    func getAllWeekdaysOfCurrentWeek(startDate: Date) -> [Date] {
        var offset = 0
        while offset < 7 {
            let calculatedDate = calendar.date(byAdding: .day, value: offset, to: startDate)!
            days.append(calculatedDate)
            offset += 1
        }
        return days
    }

    func setupSwipeGestureRecognizer() {
        let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(recognizer:)))
        swipeRight.numberOfTouchesRequired = 1
        swipeRight.direction = .right

        let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(recognizer:)))
        swipeRight.numberOfTouchesRequired = 1
        swipeRight.direction = .left

        self.collectionView.addGestureRecognizer(swipeRight)
        self.collectionView.addGestureRecognizer(swipeLeft)
    }

    @objc func handleSwipes(recognizer: UISwipeGestureRecognizer) {
        if recognizer.direction == .left {
            swipeIndex += 1
            let tempDate = calculateSwipedWeek(swipeIndex: swipeIndex)!
            print(formatter.string(from: tempDate))
            days = getAllWeekdaysOfCurrentWeek(startDate: tempDate)
            collectionView.reloadData()
        }

        if recognizer.direction == .right {
            swipeIndex -= 1
            let tempDate = calculateSwipedWeek(swipeIndex: swipeIndex)!
            print(formatter.string(from: tempDate))
            days = getAllWeekdaysOfCurrentWeek(startDate: tempDate)
            collectionView.reloadData()
        }
    }

    func calculateSwipedWeek(swipeIndex: Int) -> Date? {
        let swipedDate = calendar.date(byAdding: .weekOfYear, value: swipeIndex, to: mondayOfCurrentWeek)
        return swipedDate
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return weekdayAbreviation.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! DateCell
        cell.weekDayLabel.text = weekdayAbreviation[indexPath.item]
        cell.dateLabel.text = formatter.string(from: days[indexPath.item])
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.self.frame.width/7, height: 75)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as! DateCell
        cell.backgroundColor = UIColor(red: 112/255, green: 101/255, blue: 255/255, alpha: 1)
        cell.weekDayLabel.textColor = .white
        cell.dateLabel.textColor = .white
    }

    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as! DateCell
        cell.backgroundColor = .white
        cell.weekDayLabel.textColor = .black
        cell.dateLabel.textColor = .black
    }


    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

ViewController с SwipeWeekView :

class ViewController: UIViewController{


    let swipedWeekView: SwipeWeekView = {
        let view = SwipeWeekView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Swiped Week"
        navigationController?.navigationBar.barTintColor = .white
        self.navigationController?.navigationBar.shadowImage = UIImage()

        setupView()

    }

    func setupView() {
        view.addSubview(swipedWeekView)

        swipedWeekView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8).isActive = true
        swipedWeekView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8).isActive = true
        swipedWeekView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8).isActive = true
        swipedWeekView.heightAnchor.constraint(equalToConstant: 75).isActive = true
    }
}
...