FSCalendar 스크롤 시 캘린더가 사라지는 이유

2023. 8. 23. 18:31IOS

반응형

기존 코드

  • 다음과 같이 정상적으로 작동 가능하다.
전체 코드
import UIKit
import FSCalendar

class ViewController: UIViewController {

    @IBOutlet weak var calendarHeightAnchor: NSLayoutConstraint!

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var calendar: FSCalendar!

    private lazy var scopeGesture: UIPanGestureRecognizer = {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(swipeEvent(_:)))

        panGesture.delegate = self
        panGesture.minimumNumberOfTouches = 1
        panGesture.maximumNumberOfTouches = 2

        return panGesture
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        calendar.delegate = self
        calendar.dataSource = self

        calendar.scope = .week
        calendar.headerHeight = 0
        calendar.locale = Locale.current
        calendar.appearance.selectionColor = .red
        calendar.appearance.todayColor = .blue
        calendar.appearance.todaySelectionColor = .blue

        self.view.addGestureRecognizer(self.scopeGesture)
        self.tableView.panGestureRecognizer.require(toFail: self.scopeGesture)
    }

    @objc func swipeEvent(_ swipe: UIPanGestureRecognizer) {
        calendar.handleScopeGesture(swipe)

        UIView.animate(withDuration: 0.5) {
            self.tableView.reloadData()
        }
    }
}

extension ViewController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let shouldBegin = self.tableView.contentOffset.y <= -self.tableView.contentInset.top
        if shouldBegin {
            let velocity = self.scopeGesture.velocity(in: self.view)
            switch self.calendar.scope {
            case .month:
                return velocity.y < 0
            case .week:
                return velocity.y > 0
            @unknown default:
                return velocity.y == 0
            }
        }
        return shouldBegin
    }
}

extension ViewController: FSCalendarDelegate, FSCalendarDataSource {
    func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
        calendarHeightAnchor.constant = bounds.height
        self.view.layoutIfNeeded()
    }
}

오류 코드

@objc func swipeEvent(_ swipe: UIPanGestureRecognizer) {
    calendar.handleScopeGesture(swipe)

    switch calendar.scope {
    case .month:
        calendar.scrollDirection = .vertical
    case .week:
        calendar.scrollDirection = .horizontal
    }

    UIView.animate(withDuration: 0.5) {
        self.tableView.reloadData()
    }
}
  • FSCalendar의 스크롤 위치를 변경할 경우

  • 위와 같이 캘린더 스크롤 시 안보이는 문제가 발생함

해결법

  • 스크롤을 할 경우 scope이 바뀌는것 뿐만 아니라 scrollDirection이 바뀌길 원한다면 FSCalendarDelegateboundingRectWillChange메서드를 수정해줘야한다.
extension ViewController: FSCalendarDelegate, FSCalendarDataSource {
    func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
        calendarHeightAnchor.constant = bounds.height
        self.view.layoutIfNeeded()

        if bounds.height >= 400 {
            calendar.scrollDirection = .vertical
        } else {
            calendar.scrollDirection = .horizontal
        }
    }
}
  • 위와 같이 FSCalendarbounds를 토대로 scrollDirection을 변경해주면 된다.

반응형