class BookingController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// NEVER do something like this!!!
// create a UITableViewCell subclass
//let calendarCell = UITableViewCell()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .gray // Manager.Colors.dark
if let img = UIImage(named: "Background Image") {
addBackgroundImage(image: img)
}
setupTableContent()
}
private func addBackgroundImage(image: UIImage) {
let backgroundImage = UIImageView(image: image)
backgroundImage.frame = view.bounds
backgroundImage.alpha = 0.5
view.addSubview(backgroundImage)
}
override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent }
private func setupTableContent() {
let tableView = UITableView()
tableView.backgroundColor = .clear
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.estimatedRowHeight = 80
tableView.rowHeight = UITableView.automaticDimension
view.addSubview(tableView)
// register CalendarCell class
tableView.register(CalendarCell.self, forCellReuseIdentifier: "calendarCell")
[tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)].forEach({$0.isActive = true})
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 1 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// dequeue a CalendarCell and set its Data
let cell = tableView.dequeueReusableCell(withIdentifier: "calendarCell", for: indexPath) as! CalendarCell
cell.initData()
return cell
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { UIView() }
}
// custom table view cell
class CalendarCell: UITableViewCell {
let calendarView = CalendarView()
// we will set the .constant on this constraint to set the height of the
// calendarView (and thus the height of the collection view)
var calendarViewHeightConstraint: NSLayoutConstraint!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
calendarView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(calendarView)
calendarView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
calendarView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
calendarView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
// bottom anchor needs to have Priority less than required to avoid auto-layout complaints
let c = calendarView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
c.priority = .defaultHigh
c.isActive = true
// initial height constant doesn't matter... it will be changed when we set the data
calendarViewHeightConstraint = calendarView.heightAnchor.constraint(equalToConstant: 10.0)
calendarViewHeightConstraint.isActive = true
}
var m: Int = 0 // tiene traccia del mese
var y: Int = 0 // tiene traccia dell'anno
var totalCellsNeeded: Int = 0 // number of cell
func initData() {
let calendar = Calendar.current
m = Calendar.current.component(.month, from: Date())
y = Calendar.current.component(.year, from: Date())
let dateComponents = DateComponents(year: y, month: m)
guard let startDate = calendar.date(from: dateComponents) else { fatalError("Something is wrong with the date!") }
guard let range = calendar.range(of: .day, in: .month, for: startDate) else { fatalError("Something is wrong with the date!") }
let numberOfDaysInMonth = range.count
let startDayOfWeek = Calendar.current.component(.weekday, from: startDate)
totalCellsNeeded = numberOfDaysInMonth + (startDayOfWeek - 1)
let numRows = Int(ceil(Double(totalCellsNeeded) / Double(7)))
// we now know the Height needed for the collection view
// you said your calendar cell height is 75, so...
// cvHeight = numRows * 75
calendarViewHeightConstraint.constant = CGFloat(numRows * 75)
// give these values to the calendarView to be used
// for the collection view data
calendarView.startDayOfWeek = startDayOfWeek
calendarView.totalCellsNeeded = totalCellsNeeded
}
}
// CALENDAR VIEW
class CalendarView: UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
// these are set by the cell class
var startDayOfWeek: Int = 0
var totalCellsNeeded: Int = 0 // number of cell
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.delegate = self
collectionView.dataSource = self
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .clear
addSubview(collectionView)
collectionView.register(DaysCell.self, forCellWithReuseIdentifier: "cellDay")
collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
// no height anchor
//collectionView.heightAnchor.constraint(equalToConstant: 200).isActive = true
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
totalCellsNeeded
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellDay", for: indexPath) as! DaysCell
// startDayOfWeek is 1-based
cell.populateCell(indexPath.item - (startDayOfWeek - 1))
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
.init(width: collectionView.frame.width / 7, height: 75)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 0 }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 0 }
}
// Day CELL
class DaysCell: UICollectionViewCell {
private let dayLbl = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
dayLbl.translatesAutoresizingMaskIntoConstraints = false
addSubview(dayLbl)
dayLbl.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
dayLbl.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func populateCell(_ i: Int) -> Void {
if i >= 0 {
dayLbl.text = "\(i + 1)"
}
}
}
Comments
0 B
|👍
/👎