Reputation: 69
I am trying to implement JTAppleCalendar programmatically without storyboards, using a xib file for the cell. I have set the delegate and datasource, and implemented the required functions, but the cells are not showing. I can see that the collection view is set up and visible in the Viewcontroller(the blue square in image in link 2), and the configureCalendar() and cellForItemAt() are called, but still no data is shown.
What am I missing?
var calendarView: JTAppleCalendarView!
override func viewDidLoad() {
super.viewDidLoad()
calendarView = JTAppleCalendarView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
calendarView.register(CalendarCellView.self, forCellWithReuseIdentifier: "cell")
calendarView.ibCalendarDelegate = self
calendarView.ibCalendarDataSource = self
self.view.addSubview(calendarView)
self.view.bringSubview(toFront: calendarView)
self.calendarView.backgroundColor = UIColor.blue
}
extension TestViewController: JTAppleCalendarViewDataSource {
func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy MM dd"
let startDate = formatter.date(from: "2016 02 01")! // You can use date generated from a formatter
let endDate = Date() // You can also use dates created from this function
let parameters = ConfigurationParameters(startDate: startDate,
endDate: endDate,
numberOfRows: 6, // Only 1, 2, 3, & 6 are allowed
calendar: Calendar.current,
generateInDates: .forAllMonths,
generateOutDates: .tillEndOfGrid,
firstDayOfWeek: .sunday)
return parameters
}
func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {
}
}
extension TestViewController: JTAppleCalendarViewDelegate {
func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
let cell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: "cell", for: indexPath) as! CalendarCellView
cell.dayLabel?.text = cellState.text
print(cellState.text)
return cell
}
}
class CalendarCellView: JTAppleCell {
@IBOutlet var dayLabel: UILabel!
@IBOutlet var taskImage: UIImageView!
override func awakeFromNib() {
dayLabel.textColor = UIColor.red
self.backgroundColor = UIColor.blue
}
}
screenshot of how the collectionview currently looks
Upvotes: 4
Views: 2010
Reputation: 398
Note: It is just the starting point that gets things up and running and further customization is up to you
JTAppleCalendar version : 8.0.3
In viewDidLoad:
let cal = JTACMonthView(frame: CGRect.zero)
cal.backgroundColor = .white
cal.cellSize = 20
cal.calendarDelegate = self
cal.calendarDataSource = self
cal.register(DateCell.self, forCellWithReuseIdentifier: "calenderCellID")
view.addSubview(cal)
cal.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([cal.centerXAnchor.constraint(equalTo: view.centerXAnchor),
cal.topAnchor.constraint(equalTo: view.topAnchor),
cal.widthAnchor.constraint(equalToConstant: 200),
cal.heightAnchor.constraint(equalToConstant: 200)])
A custom cell:
class DateCell: JTACDayCell {
var dateLabel : UILabel = {
let dateLabel = UILabel()
dateLabel.text = "sample"
return dateLabel
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(dateLabel)
dateLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([dateLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
dateLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
dateLabel.heightAnchor.constraint(equalToConstant: 15)])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Finally datasource and delegate methods:
func calendar(_ calendar: JTACMonthView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTACDayCell {
let cell = calendar.dequeueReusableCell(withReuseIdentifier: calenderCellID, for: indexPath) as! DateCell
cell.dateLabel.text = cellState.text
return cell
}
func configureCalendar(_ calendar: JTACMonthView) -> ConfigurationParameters {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy MM dd"
let startDate = formatter.date(from: "2016 02 01")!
let endDate = Date()
let parameters = ConfigurationParameters(startDate: startDate,
endDate: endDate,
numberOfRows: 6, // Only 1, 2, 3, & 6 are allowed
calendar: Calendar.current,
generateInDates: .forAllMonths,
generateOutDates: .tillEndOfGrid,
firstDayOfWeek: .sunday)
return parameters
}
func calendar(_ calendar: JTACMonthView, willDisplay cell: JTACDayCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {
let cell = cell as! DateCell
cell.dateLabel.text = cellState.text
}
Note: according to this:
These 2 functions should contain the same code, therefore it is wise to have a shared function to reduce code duplication. The only difference between these two functions should be the first line of code (the dequeuing code).
The Stated functions are :
func calendar(_ calendar: JTACMonthView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath)
func calendar(_ calendar: JTACMonthView, willDisplay cell: JTACDayCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath)
Upvotes: 3
Reputation: 333
JTAppleCalendarView
's super class is UICollectionView
and it uses UICollectionViewFlowLayout
to layout the items.JTAppleCalendarView
provides CellSize
to configure the item size and you also can use UICollectionViewFlowLayout
to configure Min Spacing
.
I guess you were using xib to Custom Cell, so you have to use register(_ nib: UINib?, forCellWithReuseIdentifier identifier: String)
to register the Cell.Finally, don't forget to add constraints for the dayLabel.
calendarView's Cell Size is 40, width is 280(7 columns) and height is 240(six rows), Min Spacing for cells and lines are 0.
Upvotes: 2