为此:
protocol SelectedDay {
func tap(y:Int,m:Int,d:Int) -> Void
}
class UICalendar: UIView {
private var year:Int = 0
private var month:Int = 0
private var day:Int = 0
private var last:Int = 0
private var dayOfWeekFirst:Int = -1
private var monthName:Dictionary<Int,String> = [ 1:"Styczeń",2:"Luty",3:"Marzec",4:"Kwiecień",5:"Maj",6:"Czerwiec",7:"Lipiec",8:"Sierpień",9:"Wrzesień",10:"Październik",11:"Listopad",12:"Grudzień" ]
private let dayOfWeek:Dictionary<Int, String> = [ 1:"Pn",2:"Wt",3:"Śr",4:"Cz",5:"Pt",6:"Sb",7:"Nd" ]
private var titleColorBg:UIColor = UIColor.init(red: 36/255, green: 36/255, blue: 143/255, alpha: 0.8)
private var titleColorText:UIColor = .white
private var dayColorBg:UIColor = UIColor.init(red: 36/255, green: 36/255, blue: 143/255, alpha: 0.5)
private var dayColorText:UIColor = .white
private var selectedColorBg:UIColor = UIColor.init(red: 36/255, green: 36/255, blue: 143/255, alpha: 0.5)
private var selectedColorText:UIColor = .orange
private var borderColor:UIColor = .white
private var daysLabel:Dictionary<Int, UILabel> = [:]
private var selected:SelectedDay? = nil
struct day_info
{
var year:Int = 0
var month:Int = 0
var day:Int = 0
}
private var daysInfo:Dictionary<Int,day_info> = [:]
//initWithFrame to init view from code
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
//initWithCode to init view from xib or storyboard
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
//common func to init our view
private func setupView() {
//get current date
let date = Date()
let calendar = Calendar.current
self.year = calendar.component(.year, from: date)
self.month = calendar.component(.month, from: date)
self.day = calendar.component(.day, from: date)
self.last = self.getLastDay(year: self.year, month: self.month)
self.dayOfWeekFirst = calendar.component(.weekday, from: date) - 1
self.drawCalendar()
}
@objc private func press_day(recognized:UITapGestureRecognizer)
{
let label = recognized.view as! UILabel
let info:day_info = self.daysInfo[label.tag]!
if(self.selected != nil)
{
self.selected?.tap(y: info.year, m: info.month, d: info.day)
}
}
@objc func change_month(recognized:UITapGestureRecognizer)
{
print("change month..")
let label = recognized.view as! UILabel
if(label.tag == -1) //goback
{
if(self.month == 1)
{ self.year -= 1; self.month = 12 }
else { self.month -= 1; }
}
if(label.tag == 1) //gonext..
{
if(self.month == 12)
{ self.year += 1; self.month = 1 }
else { self.month += 1; }
}
drawCalendar()
}
func selectDay( selected:SelectedDay )
{
self.selected = selected
}
private func drawCalendar()
{
self.last = self.getLastDay(year: self.year, month: self.month)
if(self.day > self.last) { self.day = self.last }
let calendar = Calendar.current
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let date = formatter.date(from: String(self.year) + "/" + String(self.month) + "/01 10:00")
self.dayOfWeekFirst = calendar.component(.weekday, from: date!) - 1
print("Selected: (self.year) (self.month) (self.day), (self.last), (self.dayOfWeekFirst) ")
print(date)
//for select day
let cal = Calendar.current
let nowDay:Int = cal.component(.day, from: Date() )
let nowMont:Int = cal.component(.day, from: Date())
let nowYear:Int = cal.component(.year, from: Date())
var numDay:Int = -1
self.daysLabel.removeAll()
self.daysInfo.removeAll()
//clear view..
self.subviews.forEach { view in view.removeFromSuperview() }
//rows of cal..
let rowsSV:UIStackView = UIStackView(frame: CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height ) )
rowsSV.axis = .vertical
// rowsSV.backgroundColor = self.borderColor
rowsSV.alignment = .fill
rowsSV.spacing = 2
rowsSV.distribution = .fillProportionally
self.addSubview(rowsSV)
for k in 0...8
{
let ui:UIStackView = UIStackView()
ui.axis = .horizontal
ui.alignment = .fill
ui.distribution = .fillEqually
ui.spacing = 2
// ui.backgroundColor = self.borderColor
rowsSV.addArrangedSubview(ui)
//first line..
if( k == 0)
{
//prev button..
let uiPrev = UILabel()
uiPrev.text = " < "
uiPrev.backgroundColor = self.titleColorBg
uiPrev.textColor = self.titleColorText
uiPrev.textAlignment = .center
uiPrev.tag = -1
uiPrev.isUserInteractionEnabled = true
uiPrev.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(change_month(recognized:))))
ui.addArrangedSubview(uiPrev)
//month title
let uiTitle = UILabel()
uiTitle.text = String(self.year) + " " + self.monthName[self.month]!
uiTitle.backgroundColor = self.titleColorBg
uiTitle.textColor = self.titleColorText
uiTitle.textAlignment = .center
ui.addArrangedSubview(uiTitle)
//next..
let uiNext = UILabel()
uiNext.text = " > "
uiNext.backgroundColor = self.titleColorBg
uiNext.textColor = self.titleColorText
uiNext.textAlignment = .center
uiNext.tag = 1
uiNext.isUserInteractionEnabled = true
uiNext.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(change_month(recognized:))))
ui.addArrangedSubview(uiNext)
}
//day of week..
if(k == 2)
{
let d1 = UILabel()
d1.text = self.dayOfWeek[1]
d1.backgroundColor = self.titleColorBg
d1.textColor = self.titleColorText
d1.textAlignment = .center
ui.addArrangedSubview(d1)
let d2 = UILabel()
d2.text = self.dayOfWeek[2]
d2.backgroundColor = self.titleColorBg
d2.textColor = self.titleColorText
d2.textAlignment = .center
ui.addArrangedSubview(d2)
let d3 = UILabel()
d3.text = self.dayOfWeek[3]
d3.backgroundColor = self.titleColorBg
d3.textColor = self.titleColorText
d3.textAlignment = .center
ui.addArrangedSubview(d3)
let d4 = UILabel()
d4.text = self.dayOfWeek[4]
d4.backgroundColor = self.titleColorBg
d4.textColor = self.titleColorText
d4.textAlignment = .center
ui.addArrangedSubview(d4)
let d5 = UILabel()
d5.text = self.dayOfWeek[5]
d5.backgroundColor = self.titleColorBg
d5.textColor = self.titleColorText
d5.textAlignment = .center
ui.addArrangedSubview(d5)
let d6 = UILabel()
d6.text = self.dayOfWeek[6]
d6.backgroundColor = self.titleColorBg
d6.textColor = self.titleColorText
d6.textAlignment = .center
ui.addArrangedSubview(d6)
let d7 = UILabel()
d7.text = self.dayOfWeek[7]
d7.backgroundColor = self.titleColorBg
d7.textColor = self.titleColorText
d7.textAlignment = .center
ui.addArrangedSubview(d7)
}
if(k > 2)
{
//add 7 spaces
for inx in 1...7
{
if(numDay == -1 && (self.dayOfWeekFirst==inx || (inx == 7 && self.dayOfWeekFirst == 0) ) )
{
numDay = 1
}
if(numDay > self.last)
{
numDay = -2 //dont count..
}
if(numDay > 0)
{
let dx = UILabel()
dx.text = String( numDay)
dx.backgroundColor = self.dayColorBg
dx.textColor = self.dayColorText
dx.textAlignment = .center
dx.tag = numDay
if(nowDay == numDay )
{
dx.backgroundColor = self.selectedColorBg
dx.textColor = self.selectedColorText
}
ui.addArrangedSubview(dx)
dx.isUserInteractionEnabled = true
dx.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(press_day(recognized:))))
self.daysLabel[numDay] = dx
var info:day_info = day_info()
info.year = year
info.month = month
info.day = numDay
self.daysInfo[numDay] = info
numDay += 1
}else
{
let dx = UILabel()
dx.text = " "
dx.backgroundColor = self.dayColorBg
dx.textColor = self.dayColorText
dx.textAlignment = .center
ui.addArrangedSubview(dx)
}
}
}
}
}
/**
Get last day of month..
*/
private func getLastDay(year:Int, month:Int) -> Int
{
var ret:Int = -1
switch month {
case 1:
ret = 31
break
case 2:
break
case 3:
ret = 31
break
case 4:
ret = 30
break
case 5:
ret = 31
break
case 6:
ret = 30
break
case 7:
ret = 31
break
case 8:
ret = 31
break
case 9:
ret = 30
break
case 10:
ret = 31
break
case 11:
ret = 30
break
case 12:
ret = 31
break
default:
print("bad num")
}
if(month == 2)
{
ret = 28
let t4 = year % 4
let l100 = year % 100
let l400 = year % 400
if(t4 == 0 && l100 != 0)
{
ret = 29
}
if(l400 == 0)
{
ret = 29
}
}
return ret
}
}
And in ViewController (viewDidLoad) + implement protocol in your class:
let calendar = UICalendar(frame: CGRect(x: 5, y: 5, width: self.calView.bounds.width-50, height: self.calView.bounds.height-10))
calendar.selectDay(selected: self)
self.calView.addSubview(calendar)