在日历视图中禁用所有其他日期
Disabling all other days in calendar view
我有一个表单,用户将在其中 select 天,然后 select 从日历视图中获取日期..
例如:用户将首先 select 星期日和星期一 .. 然后单击日期按钮,这样日历视图将显示 ..
我希望用户能够 select 星期天或星期一的日期..我想禁用其他日期并突出显示它们,例如..
最好的方法是什么?
我看到了这两个库:
https://cocoapods.org/pods/JTAppleCalendar
https://github.com/WenchaoD/FSCalendar
但没有找到任何可以帮助我完成我需要使用它们的东西..
最好的方法是什么?
您必须将星期日视为 1,将星期一视为 2,将星期二视为 3,以此类推,将星期六视为 7。
下面全局定义
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
var arrDates = NSMutableArray()
在 viewDidLoad
.
的下一行写
arrDates = self.getUserSelectedDates([1, 2], calender: self.calendarVW)
这里的1、2表示用户选择了星期一和星期二(所以这个数组只包含那些星期日和星期一的日期)
下面是 returns 日期数组的函数,日期数组基于日期值,如 1,2 等等,直到 7。
func getUserSelectedDates(_ arrWeekDay: [Int], calender calenderVW: FSCalendar?) -> NSMutableArray {
let arrUnAvailibilityDates = NSMutableArray()
let currentDate: Date? = calenderVW?.currentPage
//get calender
let gregorianCalendar = Calendar.init(identifier: .gregorian)
// Start out by getting just the year, month and day components of the current date.
var components: DateComponents? = nil
if let aDate = currentDate {
components = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aDate)
}
// Change the Day component to 1 (for the first day of the month), and zero out the time components.
components?.day = 1
components?.hour = 0
components?.minute = 0
components?.second = 0
//get first day of current month
var firstDateOfCurMonth: Date? = nil
if let aComponents = components {
firstDateOfCurMonth = gregorianCalendar.date(from: aComponents)
}
//create new component to get weekday of first date
var newcomponents: DateComponents? = nil
if let aMonth = firstDateOfCurMonth {
newcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
}
let firstDateWeekDay: Int? = newcomponents?.weekday
//get last month date
let curMonth: Int? = newcomponents?.month
newcomponents?.month = (curMonth ?? 0) + 1
var templastDateOfCurMonth: Date? = nil
if let aNewcomponents = newcomponents {
templastDateOfCurMonth = gregorianCalendar.date(from: aNewcomponents)?.addingTimeInterval(-1)
}
// One second before the start of next month
var lastcomponents: DateComponents? = nil
if let aMonth = templastDateOfCurMonth {
lastcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
}
lastcomponents?.hour = 0
lastcomponents?.minute = 0
lastcomponents?.second = 0
var lastDateOfCurMonth: Date? = nil
if let aLastcomponents = lastcomponents {
lastDateOfCurMonth = gregorianCalendar.date(from: aLastcomponents)
}
var dayDifference = DateComponents()
dayDifference.calendar = gregorianCalendar
if arrWeekDay.count == 0 {
} else if arrWeekDay.count == 1 {
let wantedWeekDay = Int(arrWeekDay[0])
var firstWeekDateOfCurMonth: Date? = nil
if wantedWeekDay == firstDateWeekDay {
firstWeekDateOfCurMonth = firstDateOfCurMonth
} else {
var day: Int = wantedWeekDay - firstDateWeekDay!
if day < 0 {
day += 7
}
day += 1
components?.day = day
firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
}
var weekOffset: Int = 0
var nextDate: Date? = firstWeekDateOfCurMonth
repeat {
let strDT: String = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))!
arrUnAvailibilityDates.add(strDT)
weekOffset += 1
dayDifference.weekOfYear = weekOffset
var date: Date? = nil
if let aMonth = firstWeekDateOfCurMonth {
date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
}
nextDate = date
} while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
}
else {
for i in 0..<arrWeekDay.count {
let wantedWeekDay = Int(arrWeekDay[i])
var firstWeekDateOfCurMonth: Date? = nil
if wantedWeekDay == firstDateWeekDay {
firstWeekDateOfCurMonth = firstDateOfCurMonth
} else {
var day: Int = wantedWeekDay - firstDateWeekDay!
if day < 0 {
day += 7
}
day += 1
components?.day = day
firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
}
var weekOffset: Int = 0
var nextDate: Date? = firstWeekDateOfCurMonth
repeat {
let strDT = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))
arrUnAvailibilityDates.add(strDT!)
weekOffset += 1
dayDifference.weekOfYear = weekOffset
var date: Date? = nil
if let aMonth = firstWeekDateOfCurMonth {
date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
}
nextDate = date
} while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
}
}
return arrUnAvailibilityDates
}
func getSmallFormatedDate(_ localDate: Date?) -> String? {
let dateFormatter = DateFormatter()
let timeZone = NSTimeZone(name: "UTC")
if let aZone = timeZone {
dateFormatter.timeZone = aZone as TimeZone
}
dateFormatter.dateFormat = "yyyy-MM-dd"
var dateString: String? = nil
if let aDate = localDate {
dateString = dateFormatter.string(from: aDate)
}
return dateString
}
func convertCalendarDate(toNormalDate selectedDate: Date?) -> Date? {
let sourceTimeZone = NSTimeZone(abbreviation: "UTC")
let destinationTimeZone = NSTimeZone.system as NSTimeZone
var sourceGMTOffset: Int? = nil
if let aDate = selectedDate {
sourceGMTOffset = sourceTimeZone?.secondsFromGMT(for: aDate)
}
var destinationGMTOffset: Int? = nil
if let aDate = selectedDate {
destinationGMTOffset = destinationTimeZone.secondsFromGMT(for: aDate)
}
let interval1 = TimeInterval((destinationGMTOffset ?? 0) - (sourceGMTOffset ?? 0))
var localDate: Date? = nil
if let aDate = selectedDate {
localDate = Date(timeInterval: interval1, since: aDate)
}
return localDate
}
下面是 FSCalendar 代表
extension ViewController: FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance {
func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
self.view.layoutIfNeeded()
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
}
func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
arrDates = self.getUserSelectedDates([3, 4], calender: self.calendarVW)
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? {
if arrDates.contains(dateFormatter2.string(from: date)) {
return UIColor.green
} else {
return UIColor.red
}
}
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
if arrDates.contains(dateFormatter2.string(from: date)) {
return true
}
else {
return false
}
}
}
对于 JTApplecalendar 这很容易
func calendar(_ calendar: JTAppleCalendarView, shouldSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) -> Bool {
return cellState.day == .monday || cellState.day == .sunday
}
完成。
对于功能日历检查星期六或星期日然后它没有 select。
Swift 4.2的解决方案:
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
return CheckSatSunday(today: date)
}
// Check Today Is Saturday or Sunday
func CheckSatSunday(today:Date) ->Bool{
var DayExist:Bool
// let today = NSDate()
let calendar =
NSCalendar(calendarIdentifier:NSCalendar.Identifier.gregorian)
let components = calendar!.components([.weekday], from: today)
if components.weekday == 1 {
print("Hello Sunday")
self.showToast(message: "Sunday is Off")
DayExist = false
} else if components.weekday == 7{
print("Hello Saturday")
self.showToast(message: "Saturday is Off")
DayExist = false
} else{
print("It's not Saturday and Sunday ")
DayExist = true
}
print("weekday :\(String(describing: components.weekday)) ")
return DayExist
}
我有一个表单,用户将在其中 select 天,然后 select 从日历视图中获取日期..
例如:用户将首先 select 星期日和星期一 .. 然后单击日期按钮,这样日历视图将显示 ..
我希望用户能够 select 星期天或星期一的日期..我想禁用其他日期并突出显示它们,例如..
最好的方法是什么?
我看到了这两个库:
https://cocoapods.org/pods/JTAppleCalendar
https://github.com/WenchaoD/FSCalendar
但没有找到任何可以帮助我完成我需要使用它们的东西..
最好的方法是什么?
您必须将星期日视为 1,将星期一视为 2,将星期二视为 3,以此类推,将星期六视为 7。
下面全局定义
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
var arrDates = NSMutableArray()
在 viewDidLoad
.
arrDates = self.getUserSelectedDates([1, 2], calender: self.calendarVW)
这里的1、2表示用户选择了星期一和星期二(所以这个数组只包含那些星期日和星期一的日期)
下面是 returns 日期数组的函数,日期数组基于日期值,如 1,2 等等,直到 7。
func getUserSelectedDates(_ arrWeekDay: [Int], calender calenderVW: FSCalendar?) -> NSMutableArray {
let arrUnAvailibilityDates = NSMutableArray()
let currentDate: Date? = calenderVW?.currentPage
//get calender
let gregorianCalendar = Calendar.init(identifier: .gregorian)
// Start out by getting just the year, month and day components of the current date.
var components: DateComponents? = nil
if let aDate = currentDate {
components = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aDate)
}
// Change the Day component to 1 (for the first day of the month), and zero out the time components.
components?.day = 1
components?.hour = 0
components?.minute = 0
components?.second = 0
//get first day of current month
var firstDateOfCurMonth: Date? = nil
if let aComponents = components {
firstDateOfCurMonth = gregorianCalendar.date(from: aComponents)
}
//create new component to get weekday of first date
var newcomponents: DateComponents? = nil
if let aMonth = firstDateOfCurMonth {
newcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
}
let firstDateWeekDay: Int? = newcomponents?.weekday
//get last month date
let curMonth: Int? = newcomponents?.month
newcomponents?.month = (curMonth ?? 0) + 1
var templastDateOfCurMonth: Date? = nil
if let aNewcomponents = newcomponents {
templastDateOfCurMonth = gregorianCalendar.date(from: aNewcomponents)?.addingTimeInterval(-1)
}
// One second before the start of next month
var lastcomponents: DateComponents? = nil
if let aMonth = templastDateOfCurMonth {
lastcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
}
lastcomponents?.hour = 0
lastcomponents?.minute = 0
lastcomponents?.second = 0
var lastDateOfCurMonth: Date? = nil
if let aLastcomponents = lastcomponents {
lastDateOfCurMonth = gregorianCalendar.date(from: aLastcomponents)
}
var dayDifference = DateComponents()
dayDifference.calendar = gregorianCalendar
if arrWeekDay.count == 0 {
} else if arrWeekDay.count == 1 {
let wantedWeekDay = Int(arrWeekDay[0])
var firstWeekDateOfCurMonth: Date? = nil
if wantedWeekDay == firstDateWeekDay {
firstWeekDateOfCurMonth = firstDateOfCurMonth
} else {
var day: Int = wantedWeekDay - firstDateWeekDay!
if day < 0 {
day += 7
}
day += 1
components?.day = day
firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
}
var weekOffset: Int = 0
var nextDate: Date? = firstWeekDateOfCurMonth
repeat {
let strDT: String = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))!
arrUnAvailibilityDates.add(strDT)
weekOffset += 1
dayDifference.weekOfYear = weekOffset
var date: Date? = nil
if let aMonth = firstWeekDateOfCurMonth {
date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
}
nextDate = date
} while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
}
else {
for i in 0..<arrWeekDay.count {
let wantedWeekDay = Int(arrWeekDay[i])
var firstWeekDateOfCurMonth: Date? = nil
if wantedWeekDay == firstDateWeekDay {
firstWeekDateOfCurMonth = firstDateOfCurMonth
} else {
var day: Int = wantedWeekDay - firstDateWeekDay!
if day < 0 {
day += 7
}
day += 1
components?.day = day
firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
}
var weekOffset: Int = 0
var nextDate: Date? = firstWeekDateOfCurMonth
repeat {
let strDT = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))
arrUnAvailibilityDates.add(strDT!)
weekOffset += 1
dayDifference.weekOfYear = weekOffset
var date: Date? = nil
if let aMonth = firstWeekDateOfCurMonth {
date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
}
nextDate = date
} while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
}
}
return arrUnAvailibilityDates
}
func getSmallFormatedDate(_ localDate: Date?) -> String? {
let dateFormatter = DateFormatter()
let timeZone = NSTimeZone(name: "UTC")
if let aZone = timeZone {
dateFormatter.timeZone = aZone as TimeZone
}
dateFormatter.dateFormat = "yyyy-MM-dd"
var dateString: String? = nil
if let aDate = localDate {
dateString = dateFormatter.string(from: aDate)
}
return dateString
}
func convertCalendarDate(toNormalDate selectedDate: Date?) -> Date? {
let sourceTimeZone = NSTimeZone(abbreviation: "UTC")
let destinationTimeZone = NSTimeZone.system as NSTimeZone
var sourceGMTOffset: Int? = nil
if let aDate = selectedDate {
sourceGMTOffset = sourceTimeZone?.secondsFromGMT(for: aDate)
}
var destinationGMTOffset: Int? = nil
if let aDate = selectedDate {
destinationGMTOffset = destinationTimeZone.secondsFromGMT(for: aDate)
}
let interval1 = TimeInterval((destinationGMTOffset ?? 0) - (sourceGMTOffset ?? 0))
var localDate: Date? = nil
if let aDate = selectedDate {
localDate = Date(timeInterval: interval1, since: aDate)
}
return localDate
}
下面是 FSCalendar 代表
extension ViewController: FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance {
func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
self.view.layoutIfNeeded()
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
}
func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
arrDates = self.getUserSelectedDates([3, 4], calender: self.calendarVW)
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor? {
if arrDates.contains(dateFormatter2.string(from: date)) {
return UIColor.green
} else {
return UIColor.red
}
}
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
if arrDates.contains(dateFormatter2.string(from: date)) {
return true
}
else {
return false
}
}
}
对于 JTApplecalendar 这很容易
func calendar(_ calendar: JTAppleCalendarView, shouldSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) -> Bool {
return cellState.day == .monday || cellState.day == .sunday
}
完成。
对于功能日历检查星期六或星期日然后它没有 select。 Swift 4.2的解决方案:
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
return CheckSatSunday(today: date)
}
// Check Today Is Saturday or Sunday
func CheckSatSunday(today:Date) ->Bool{
var DayExist:Bool
// let today = NSDate()
let calendar =
NSCalendar(calendarIdentifier:NSCalendar.Identifier.gregorian)
let components = calendar!.components([.weekday], from: today)
if components.weekday == 1 {
print("Hello Sunday")
self.showToast(message: "Sunday is Off")
DayExist = false
} else if components.weekday == 7{
print("Hello Saturday")
self.showToast(message: "Saturday is Off")
DayExist = false
} else{
print("It's not Saturday and Sunday ")
DayExist = true
}
print("weekday :\(String(describing: components.weekday)) ")
return DayExist
}