Я работаю над проектом, где мне нужно горизонтальное представление календаря в верхней части экрана. В этом календаре будет отображаться общее количество 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
}
}