Swift FSCalendar Interactive Scope Gesture 以编程方式

Swift FSCalendar Interactive Scope Gesture programmatically

我正在使用 FSCalendar to create a calendar for my app but I can not get the Interactive Scope Gesture to work. I have downloaded the example project and read through the documentation but it still crashes with this error Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value on line calendarHeightConstraint.constant = 350. All I'm trying to achieve is the exact same as the documentation shows with the Interactive Scope Gesture 但以编程方式。

var calendarHeightConstraint: NSLayoutConstraint!

let calendarView: FSCalendar = {
    let cl = FSCalendar()
    cl.allowsMultipleSelection = false
    return cl
}()

let collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor(named: "backgroundColor")
    cv.showsVerticalScrollIndicator = false
    cv.showsHorizontalScrollIndicator = false
    return cv
}()

fileprivate lazy var scopeGesture: UIPanGestureRecognizer = {
    [unowned self] in
    let panGesture = UIPanGestureRecognizer(target: self.calendarView, action: #selector(self.calendarView.handleScopeGesture(_:)))
    panGesture.delegate = self
    panGesture.minimumNumberOfTouches = 1
    panGesture.maximumNumberOfTouches = 2
    return panGesture
}()

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = UIColor(named: "backgroundColor")
    collectionView.delegate = self
    collectionView.dataSource = self
    calendarView.delegate = self
    calendarView.dataSource = self
    
    calendarHeightConstraint.constant = 350

    self.calendarView.select(Date())
    
    self.view.addGestureRecognizer(self.scopeGesture)
    self.calendarView.addGestureRecognizer(self.scopeGesture)
    self.calendarView.scope = .week
    
    setupLayout()
    setupCollectionView()
}

func setupLayout() {
    
    view.addSubview(calendarView)
    calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 350)

    view.addSubview(collectionView)
    collectionView.anchor(top: calendarView.bottomAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 15, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}

func setupCollectionView() {
    
    collectionView.register(CalendarCollectionCell.self, forCellWithReuseIdentifier: cellId)
    collectionView.dataSource = self
    collectionView.delegate = self
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CalendarCollectionCell
    
    return cell
}

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

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

func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
    self.calendarHeightConstraint.constant = bounds.height
    self.view.layoutIfNeeded()
}

你没有初始化

 var calendarHeightConstraint: NSLayoutConstraint!

或 link 它作为一个出口,因此它是 nil ,你需要 link 这里

calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 350)

因此您可以根据需要使用它constant,因此您可以

NSLayoutConstraint.activate([
   // add left , right and top constraints
])

除了

calendarHeightConstraint = calendarView.heightAnchor.constraint(equalToConstant: 350)
calendarHeightConstraint.isActive = true

不要尝试在上面两行之前使用 calendarHeightConstraint ,因为这会导致 nil 崩溃

您可以通过做两件事来解决这个问题。

  1. viewDidLoad 中删除行 calendarHeightConstraint.constant = 350

  2. 初始化setupLayout中的calendarHeightConstraint

而不是:

calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 350)

使用:

calendarView.anchor(top: topLayoutGuide.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 75, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width, height: 0)
calendarHeightConstraint = calendarView.heightAnchor.constraint(equalToConstant: 350)
calendarHeightConstraint.isActive = true